先后端传参过程当中不得不面对的转码问题

数据传递转码
数据在传输的过程当中,浏览器会对数据进行编码,假如我如今有一条数据 {"name": "测试"},若是咱们经过 get 方法传递数据,这条数据会被拼接到 url 请求的后面,如:localhost:8080/src/text.html?name=测试。html

uri自己是采用ASCII编码的,因此若是是非 ASCII 编码集的字符在传输时都会被编码,编码方法和 encodeURI 的编码规则相同,可是这里的编码规则是由浏览器控制的,不一样的浏览器采用的编码方式 (UTF-8,GBK) 不同,被编码的数据发送给服务器,服务器用 iso-8859-1 编码对数据解码,后端人员经过 request.getParameter("name") 获取参数数据,且得到的数据都是通过解码过的,而解码过程当中程序里没法指定,对于 get 请求得到的数据 request.setCharacterEncoding("字符集") 指定解码规则无效。前端

若是是 post 方法传递数据,浏览器也会对数据进行编码,若是咱们在 ajax 请求头里面设置了 setRequestHeader("ContentType","application/x-www-form-urlencoded;charset=UTF-8"); 浏览器就会以charset值进行编码,若是没有设置则由网页 meta 标签的 charset 属性决定,被编码过的数据发送给服务器,服务器用 iso-8859-1 编码对数据解码,对于post请求发来的数据后端人员可使用
request.setCharacterEncoding("字符集") 指定解码规则。ajax

相信你已经找出了乱码的缘由,因为 get 方法传的的数据,浏览器的转码规则和服务器的解码规则不一致出现了乱码,咱们通常是怎么解决的呢?get 方式发送的数据若是有中文和特殊字符前端会先使用 encodeURI() 方法转码,这样 url 里面的就都是 ASCII 编码集的字符,省去了浏览器的转码,且 encodeURI() 的转码规则可控,受网页 meta 头的 charset 属性影响,json

  1. 标签的 charset 属性为 utf-8 时:
var data = '百度&%$#@baidu';
    console.log(encodeURI(data));
    // %E7%99%BE%E5%BA%A6&%25$#@baidu
    console.log(encodeURIComponent(data));
    // %E7%99%BE%E5%BA%A6%26%25%24%23%40baidu
  1. 标签的 charset 属性为 GBK 时:
var data = '百度&%$#@baidu';
console.log(encodeURI(data));
// %E9%90%A7%E6%83%A7%E5%AE%B3&%25$#@baidu
console.log(encodeURIComponent(data));
// %E9%90%A7%E6%83%A7%E5%AE%B3%26%25%24%23%40baidu

后端人员获取到用iso-8859-1解码后的数据通常先还原回字节码,而后用先后端协定的方式解码数据,还能够在服务器的配置文件里面进行配置解码规则。而post请求发送的数据可使用request.setCharacterEncoding("字符集")指定解码规则来达到先后端转码统一。后端

当咱们须要传递的数据量大,结构复杂,业务场景,技术实现须要的时候咱们就又会发现,乱码的问题依然存在,好比浏览器

  • json格式的数据因为特殊字符致使数据解析出现问题,
  • xml格式数据因为特殊字符破坏xml格式致使数据解析出现问题,
  • 先后端一些语言自带的转码方法对一些特殊字符转码结果不一致,以及并不是全部特殊字符都会被转码...

若是咱们使用 encodeURI 或者 encodeURIComponent 编码传输到后端,后端解码以后的数据总会由于一些特殊字符的转码不一致致使结果不同,若是再加上 md5 校验之类的,前端传递的数据就会由于 md5 不一样没法解析入库。服务器

那么这个时候咱们就该考虑有没有一种转码规则能够解决以上全部的问题呢?base64 转码你值得拥有。app

base64转码post

base64 编码是从二进制到字符的过程,编码受 html 页面头部 mate;标签的 charset 属性影响,charset 属性不一样,编码转为二进制时,产生的二进制也是不同的,因此最终产生的 base64 字符也不同。测试

  1. mate 标签的 charset 属性为 utf-8 时:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>base64</title>
</head>
<body>
<script src="base64.min.js"></script>
<script>
var data = '百度&%$#@baidu';
console.log(base64encode(data));
// fqYmJSQjQGJhaWR1
</script>
</body>
  1. mate 标签的 charset 属性为 GBK 时:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="GBK">
<title>base64</title>
</head>
<body>
<script src="base64.min.js"></script>
<script>
var data = '百度&%$#@baidu';
console.log(base64encode(data));
// J+ezJiUkI0BiYWlkdQ==
</script>
</body>

有关 base64 转码原理有兴趣可自行百科。

总结

因此工做中若是涉及到文本框输入等复杂的内容数据传递为了不中文乱码以及各类特殊符号带来的困扰就使用 base64 转码传递。 若是只是URL里面的传递简单的参数可使用 encodeURI 和 encodeURIComponent 等转码。

相关文章
相关标签/搜索