天天看點

小程式中文亂碼 及request值擷取方式的差別

在公司項目中,小程式發起請求時,最基本的結構是:

wx.request({
    url: "", 
    method: 'POST',
    data:{
        //這裡是多組key : value
    },
    success(res) {
       wx.showToast({
          title:'儲存成功',
          icon: 'success',
          duration: 2000
        })
    },
    fail(res) {
      wx.showToast({
          title: '儲存失敗',
        })
    }
})
           

微信小程式預設的’Content-Type’值為 "application/json",即傳遞的是JSON串。

參數若包含中文,則背景擷取到的資訊為亂碼,通過查閱資料,對于wx.request中文亂碼的問題,可以通過在請求提體中添加如下代碼

header:{'content-type': 'application/x-www-form-urlencoded;charset=utf-8',}
           

即請求體應該是:

var jsondata = {
    key1: value1,
    key2: value2,
    ...
},
jsondata = JSON.stringify(jsondata) 

wx.request({
    url: '',
    data: {
        jsonData: jsondata
    },
    header: {
        'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
    }, 
    method: 'POST',
    success: function (res) {}
})
           

需要注意的是,此處的data,若為簡單的前面傳遞鍵值對,則從微信開發者工具中的調試視窗中的Network看到的是:送出的資料是Form Data(鍵值對),而不是JSON字元串!因為微信小程式解析到’Content-Type’: ‘application/x-www-form-urlencoded;charset=utf-8’,是以送出的是Form Data。若需要送出json字元串,則解決思路可以是:既然小程式送出的是Form Data,那可以把一個JSON字元串當做一個value值,而key值可以取任何值(此處即為jsonData)。即你的Form Data隻需要包含一組鍵值對,在這一組鍵值對中,key是任意值(jsonData),而value是JSON字元串。

背景擷取資料

當按照原始方式的時候(即未添加header),背景擷取json串并解析,沒有異常,但若包含中文的時候,就會提示jsonObject需要以“{”開頭,背景擷取方式是:

IOUtils.toString(request.getInputStream())
           

此時按照上面提到的方式,将header添加後,仍有異常,通過分析request的擷取方式,需按照如下方式進行擷取:

request.getParameter("jsonData")
           

查閱資料分析request下擷取參數值的方式如下:

request.getParameter()、request.getInputStream()和request.getReader()

三者進行差別分析:

application/x- www-form-urlencoded是Post請求預設的請求體内容類型,也是form表單預設的類型。Servlet API規範中對該類型的請求内容提供了request.getParameter()方法來擷取請求參數值。但當請求内容不是該類型時,需要調用request.getInputStream()或request.getReader()方法來擷取請求内容值。

當請求體内容(注意:get請求沒有請求體)類型是application/x- www-form-urlencoded時也可以直接調用request.getInputStream()或request.getReader()方法擷取到請求内容再解析出具體都參數,但前提是還沒調用request.getParameter()方法。此時當request.getInputStream()或request.getReader()擷取到請求内容後,無法再調request.getParameter()擷取請求内容。即對該類型的請求,三個方法互斥,隻能調其中一個。今天遇到一個Controller請求經過Spring MVC 的RequestMapping處理後,隻能通過request.getParameter()擷取到參數、無法通過request.getInputStream()和request.getReader()讀取内容很可能就是因為在請求經過Spring MVC時已調用過request.getParameter()方法的原因。

注意:在一個請求鍊中,請求對象被前面對象方法中調用request.getInputStream()或request.getReader()擷取過内容後,後面的對象方法裡再調用這兩個方法也無法擷取到用戶端請求的内容,但是調用request.getParameter()方法擷取過内容後,後面的對象方法裡依然可以調用它擷取到參數的内容。

當請求體内容是其它類型時,比如 multipart/form-data或application/json時,無法通過request.getParameter()擷取到請求内容,此時隻能通過request.getInputStream()和request.getReader()方法擷取請求内容,此時調用request.getParameter()也不會影響第一次調用request.getInputStream()或request.getReader()擷取到請求内容。

request.getInputStream()傳回請求内容位元組流,多用于檔案上傳,request.getReader()是對前者傳回内容的封裝,可以讓調用者更友善字元内容的處理(不用自己先擷取位元組流再做字元流的轉換操作)。