天天看点

小程序中文乱码 及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()是对前者返回内容的封装,可以让调用者更方便字符内容的处理(不用自己先获取字节流再做字符流的转换操作)。