JSON 序列化及解析转换成 Object 物件

JavaScript 转换为 JSON 字符串,以便在 Fetch API 请求中传送数据。JavaScript Built-In 全域的方法 Fetch API 接口传送处理 JSON.stringify 序列化 JSON.parse 解析转换成 Object 物件,前端 JavaScript Fetch 请求与后端伺服器基于 Microsoft ASP.NET 网页和网站开发的框架解析 JSON。使用 POST 方法及配合 body 属性设定传递需求参数,因为传递「中文」可能会出现乱码,所以使用 encodeURI 转码及 JSON.stringify 转换为字符串化格式传递。

const url = "Product-Request.aspx";

fetch(url, {
  method: "POST",
  body: encodeURI(JSON.stringify({
    series: "扭力限制器",
    torque: 6000
  })),
  headers: {
    "Content-Type": "application/x-www-form-urlencoded;charset=utf-8"
  }
}).then(function (response) {
  return response.json(); // 返回 json 物件
}).then(function (jsonString) {
  let result = JSON.parse(jsonString);
  console.log(result);
  let product = (result.product);
  console.log(product);
});

送出传递的 body 属性设定 JSON.stringify 转换为字符串。
实际是 %7B%22series%22:%22%E6%89%AD%E5... encodeURI 转码内容。

{"series":"扭力限制器","torque":6000} ""



于后端 ASPX 解析 JSON

JavaScriptSerializer

后端伺服器 Product-Request.aspx 接收到的字符串,转换程式码使用 JavaScriptSerializer Deserialize() 解析并且存放到 Dictionary 字典「键/值」使用其索引键读取值,经过「伺服器处理」的结果再由 Serialize() 序列化字符串返回内容。

<%@ Import Namespace="System.Web.Script.Serialization" %>
<%
Response.ContentType = "application/x-www-form-urlencoded"

Dim formJsonString = HttpUtility.UrlDecode(Request.Form().ToString())
Dim serializer As New JavaScriptSerializer()
Dim formDicts = serializer.Deserialize(Of Dictionary(Of String, Object))(formJsonString)

Dim SqlItem As String = "{""YA208"":2500,""YA605"":3600}" '假设为 SQL 请求结果

Dim odString As String = "{""series"":""" & formDicts.Item("series") & """,""product"":" & SqlItem & "}"
Dim odSerialize = serializer.Serialize(odString)
Response.Write(odSerialize)
%>

经过由 Serialize 序列化字符串内容。

"{\"series\":\"扭力限制器\", \"product\":{\"YA208\":2500,\"YA605\":3600}}"


JavaScript JSON.parse(jsonString) 解析转换成 Object 内容。

console.log(result);
let product = (result.product);
console.log(product);

返回内容中读取到的值。

Object { series: "扭力限制器", product: { YA208: 2500, YA605: 3600 } }
Object { YA208: 2500, YA605: 3600 }



HttpUtility.UrlEncode(String) 转换成 URL 编码的字串

但因为前述传递「中文」可能会出现乱码,所以返回的结果也要经过 URI 转码处理。

Response.Write( HttpUtility.UrlEncode(odSerialize) )

这样就可以将返回的结果 %22%7b%5c%22series%5c%22%3a%5c%22%e6%89%ad... 转码处理。


但是因格式不同、返回的部份是字串格式 JavaScript 需要修改一下。

返回 text 物件 response.text() 字串格式,先经过 decodeURIComponent() 解码再进行 JSON.parse()。

const url = "Product-Request.aspx";

fetch(url, {
  method: "POST",
  body: encodeURI(JSON.stringify({
    series: "扭力限制器",
    torque: 6000
  })),
  headers: {
    "Content-Type": "application/x-www-form-urlencoded;charset=utf-8"
  }
}).then(function (response) {
  return response.text(); // 返回 text 物件
}).then(function (textString) {
  let result = JSON.parse(JSON.parse(decodeURIComponent(textString))); // 解析
  console.log(result);
  let product = (result.product);
  console.log(product);
});

使用 decodeURIComponent 将已经编码的 URI 加以解码。这里 JSON.parse 出现两次「两次解析」,我也不知道因为两次才是 Object 物件、只 parse 一次解析看起来没错,但他是 String 字串的格式。
查阅 docs.microsoft.com 针对 .NET Framework 4.7.2 和更新版本,使用命名空间中的 System.Text.Json API 进行序列化和还原序列化。针对旧版的 .NET Framework,使用 Newtonsoft.Json。但是需要伺服器端版本支持。




关于 ASPX UrlEncode 编码、UrlDecode 解码

HttpUtility.UrlEncode(String) 将 URL 字串编码。提供处理 Web 要求时用于编码和解码 URL 的方法。如果在 HTTP 资料流程中传递空白和标点符号之类的字元,在接收端可能会错误解译。UrlEncode 会将每个空白字元转换成加号字元 + 而 UrlPathEncode 会将每个空白字元转换成字串 %20。

Dim SourceCharacter As String = "字串 编码"
Dim EnCharacter As String = HttpUtility.UrlEncode(SourceCharacter)

%e5%ad%97%e4%b8%b2+%e7%b7%a8%e7%a2%bc

JavaScript encodeURIComponent()

encodeURIComponent("字串 编码")

%E5%AD%97%E4%B8%B2%20%E7%B7%A8%E7%A2%BC

除了大小写,解码可以通用或是以 Ucase() 转大写保持一致。

但是需要注意「空格」部份 %20+ 的差异及 ~%7e'%27

如果再将传递过程以 Base64 编码参考文章 Base64 UTF8 文字编码、解码


encodeURIComponent("A B+C") // A%20B%2BC  (JavaScript)
HttpUtility.UrlEncode("A B+C") ' A+B%2bC
Replace(Ucase(HttpUtility.UrlEncode("A B+C")),"+" ,"%20") ' A%20B%2BC

在网页开发中常需要使用 JavaScript 来发送请求给后端伺服器,并接收回传的资料。其中常用的资料格式是 JSON 资料交换格式,可以用来传递复杂的资料结构。但是使用 JavaScript 的 Fetch API 来发送 JSON 资料给后端伺服器,并且后端伺服器是使用 ASPX 来处理请求,可能会遇到乱码问题。这是因为 Fetch API 预设会将 JSON 资料转换为 UTF-8 编码,而 ASPX 预设会将请求的内容解析为 ISO-8859-1 编码。这样就会造成编码不一致,导致乱码的产生。