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 編碼。這樣就會造成編碼不一致,導致亂碼的產生。