在项目中碰到了ajax传来的参数,后台接收值乱码(如下图)的问题 在此记录一下

前台:

后台:


解决问题

  • 为什么需要编码
  • 怎样编码
  • 实际出现的问题解决方法

1.为什么需要编码?

URL 只能使用 ASCII 字符集来通过因特网进行发送。
也就是说URL只能使用英文字母、阿拉伯数字和某些标点符号,不能使用其他文字和符号

 

这意味着 如果URL中有汉字,就必须编码后使用。

但是麻烦的是 标准的国际组织并没有规定具体的编码方法,而是交给应用程序(浏览器)自己决定。

这导致"URL编码"成为了一个混乱的领域。 

1.1 浏览器对于中文的编码

Chrome浏览器和火狐的浏览器是一样的如下图,"文"和"章"的utf-8编码分别是"E6 96 87"和"E7 AB A0" ,

下图所示的"%e6%96%87%e7%ab%a0"就是按照顺序,在每个字节前加上%而得到的


Edge浏览器和IE浏览器是一样的,如下图 这个的编码方式我没看出来,希望高手指点

1.2 需要编码的原因还有几点:

你有没有想过,Ukey=value这种传参方式式中, Value中包含 ?或者 = 怎么办呢

你有没有想过,不同的操作系统、浏览器、不同的网页字符集(charset)会对你的传值造成影响呢

如果你都考虑过,毫无疑问你早就知道需要编码的原因了


2.怎样编码?

Url编码通常也被称为百分号编码(percent-encoding),是因为它的编码方式非常简单,

使用%百分号加上两位的字符——0123456789ABCDEF——代表一个字节的十六进制形式

对于ASCII字符,字母a 在ASCII码中对应的字节是0x61,那么Url编码之后得到的就是%61,

字母abc, url编码后得到的就是%61%62%63

对于非ASCII字符,RFC文档建议使用utf-8对其进行编码得到相应的字节,然后对每个字节执行百分号编码。

如"中文"使用UTF-8字符集得到的字节为0xE4 0xB8 0xAD 0xE6 0x96 0x87,经过Url编码之后得到"%E4%B8%AD%E6%96%87"。

 
使用Javascript先对URL编码,然后再向服务器提交,不要给浏览器插手的机会
这样就能保证客户端只用一种编码方法向服务器发出请求


3.实际出现的问题解决方法

首先说一下js的三种编码函数,escape、encodeURI和encodeURIComponent

3.1.escape函数:

js中编码出生最早的一个,不提倡使用,原因是它不符合我上边(【怎样】)说的url编码原则

真正作用是:

返回一个字符的Unicode编码值,为的是方便他们能在所有计算机上可读

具体规则是:

所有空格、标点以及其他非ASCII字符都用%xx编码替换; 例如空格返回的是%20 字符值大于255的字符以%uxxxx格式储存

所以以后如果看到%u的编码,那就是escape函数

看下边这个列子 你就很清楚的知道它的具体转换规则了


项目中使用:

前台:

function HandlerAddress() {
$.ajax({
type: "get",
//用的是js的escape方法
url: "handler/Handler.ashx?address=" + escape("朝阳区大屯路东"),
contentType: "application/json; charset=utf-8",
success: function (data) {
//todo成功方法
},
error: function (XMLhttpRequest, textStatus, errorThrown) {
//todo失败方法
}
})

后台:

QueryString 这个函数会自动解码,所以不需要写什么解码的语句。

还有一点需要注意的是:

escape()不对"+"编码。但是我们知道,网页在提交表单的时候,如果有空格,则会被转化为+字符。服务器处理数据的时候,会把+号处理成空格。所以,使用的时候要小心。

3.2.encodeURI函数

这个函数才是javascript中真正用来对URL编码的函数

规则就是我上面第二部分所说的,采用utf-8编码。

前台:

后台:

用这个方法会存在乱码的问题,看到很多人问这问题的时候,回答者都是让采用escape这种方法,难道这样问题就解决了吗?

如果我想用Jquery的serialize()方法来获取表单值并且序列化(标准URL编码)传到后台就不方便用escape啦


解决乱码问题:

出现乱码的原因是我的web config文件里有这样的配置:

<globalization requestEncoding="gb2312" responseEncoding="gb2312" />

解决方案1:去掉这个设置或者改成utf-8的(这个方案的利害不用说,尤其是在项目已经快完成的时候)

解决方案2:利用ajax的post方法,或者用Get方法,但必须作为方法的Data参数,这样在后台接收到的数据不会被编码

前台:

$.ajax({
type: "get",
//用的是js的encodeURI方法
url: "handler/Handler.ashx",
//作为Data参数
data: { address: encodeURI("朝阳区大屯路东") }, contentType: "application/json; charset=utf-8",
success: function (data) {
//todo成功方法
},
error: function (XMLhttpRequest, textStatus, errorThrown) {
//todo失败方法
}
})

后台:需要手动解码一次

string ad =HttpUtility.UrlDecode(context.Request["address"]);

HttpUtility.UrlDecode和Server.UrlDecode不同的是,HttpUtility.UrlDecode是有重载的,可以指定编码的方式

例如:

string adsx = HttpUtility.UrlDecode(context.Request.QueryString["address"],System.Text.Encoding.UTF8);

解决方案3:获取已编码的原始数据,自己进行解码

通过观察Request的对象,可以发现context.Request.Url.Query是未解码的数据,这就太棒了

代码:

string address= HttpUtility.ParseQueryString(context.Request.Url.Query, Encoding.UTF8)["address"];

解决方案4(探讨):先将QueryString解码的数据按照他原来的方式进行编码,然后再用utf8进行解码,这个方法有点问题,最后一个字符会出现乱码,还没找到原因..

在将数据编码的时候,就不是原来的浏览器发送的编码值了,正确的是最后边应该是%9C,但现在却是%3f

3.3.encodeURIComponent函数

与encodeURI()的区别是,它用于对URL的组成部分进行个别编码,而不用于对整个URL进行编码。

因此,"; / ? : @ & = + $ , #",这些在encodeURI()中不被编码的符号,在encodeURIComponent()中统统会被编码

具体的编码规则是和encodeURI函数是一样的,如下,encodeURI不会编码 ?@,而encodeURIComponent会

encodeURIComponent这个函数就和他的名字一样,是对URI中的一个组件进行编码,不能用于全部的URI

初次写文章,如果有错误或者表达的不清楚,尽管提出来,吐槽黑我 都可以 反正我脸皮厚

参考:阮一峰-关于URL编码

URL编码与解码的更多相关文章

  1. Web开发须知:URL编码与解码

    通常如果一样东西需要编码,说明这样东西并不适合传输.原因多种多样,如Size过大,包含隐私数据,对于Url来说,之所以要进行编码,是因为Url中有些字符会引起歧义. 例如,Url参数字符串中使用key ...

  2. java中的url 编码与解码

    什么是application/x-www-form-urlencoded字符串? 答:它是一种编码类型.当URL地址里包含非西欧字符的字符串时,系统会将这些字符转换成application/x-www ...

  3. python接口自动化测试十三:url编码与解码

    # url编码与解码 from urllib import parse url = 'http://zzk.cnblogs.com/s/blogpost?Keywords=中文' a = '中文' b ...

  4. LR URL编码和解码方法

    问题:URL=http://www.baidu.com/s?wd=%E6%B5%B7%E6%B7%80%E9%BB%84%E5%BA%84"中要对%E6%B5%B7%E6%B7%80%E9% ...

  5. Oracle url编码与解码

      Oracle url编码与解码 CreateTime--2018年3月30日17:26:36 Author:Marydon 一.url编码 实现方式:utl_url.escape() 说明:utl ...

  6. python中的URL编码和解码

    python中的URL编码和解码:test.py # 引入urllib的request模块 import urllib.request url = 'https://www.douban.com/j/ ...

  7. Delphi编码与签名【URL编码与解码,Base64编码与解码,MD5加密,HMAC-SHA1、HMAC-SHA224、HMAC-SHA256、HMAC-SHA384和HMAC-SHA512签名】

    作者QQ:(648437169) 点击下载➨delphi编码与签名 [Delphi编码与签名]URL编码与解码,Base64编码与解码,MD5加密,HMAC-SHA1.HMAC-SHA224.HMAC ...

  8. URL编码和解码工具

    开发中发现需要进行URL的编解码,每次百度出来的还带广告而且比较慢,写了一个本地的工具,比较简单,希望对大家有帮助. <!DOCTYPE html PUBLIC "-//W3C//DT ...

  9. IOS URL 编码和解码

    1.url编码 ios中http请求遇到汉字的时候,需要转化成UTF-8,用到的方法是: NSString * encodingString = [urlString stringByAddingPe ...

随机推荐

  1. iOS音频AAC视频H264编码 推流最佳方案

    iOS音频AAC视频H264编码 推流最佳方案 项目都是个人的调研与实验,可能很多不好或者不对的地方请多包涵. 1    功能概况 *  实现音视频的数据的采集 *  实现音视频数据的编码,视频编码成 ...

  2. DBA日常工作内容和职责

    1.统计数据库总容量 按表空间分别统计: 总容量(单位为M): 2.计算用户下所有对象大小 3计算USERS表空间的大小 4计算该USERS表空间对象大小 ---------------------- ...

  3. td内容过长,省略号表示

    .word{ min-width:100px; max-width:200px; overflow:hidden; white-space:nowrap; text-overflow:ellipsis ...

  4. c语言.大数的输出

    转化成字符串,再用for循环输出: #include <stdio.h>#include <string.h>int main(){  char s[32];   int d, ...

  5. Windows7无法访问(远程登录)Windows 2003共享问题解决

    解决方法: 1.直接按下win+r键,输入gpedit.msc,打开本地组策略编辑器. 2.找到“计算机配置”-->“Windows设置”-->“安全设置”-->“本地策略”--&g ...

  6. 【iCore3 双核心板_FPGA】Quartus 如何生成jic文件

    PDF下载: http://pan.baidu.com/s/1i5lQ0Rj iCore3 购买链接: https://item.taobao.com/item.htm?id=524229438677

  7. 【转载】James Whittaker:经营成功的测试职业生涯

    转注:这篇文章出自 James A. Whittaker ,但未找到原始出处/译者.如果有知道原始出处的朋友,可在评论这留言. 你是如何开始做测试工作的?  1989年,我在田纳西大学读研究生的时候, ...

  8. java变量和方法的覆盖和隐藏(翻译自Java Tutorials)

    隐藏变量 在一个类里,如果一个变量的名字和父类的变量的名字一样,即使他们的类型不一样,那么在子类中,父类的同名变量无法直接通过变量名访问.但是,父类的同名变量可以通过super访问.一般来说,不推荐隐 ...

  9. Maven:解决-Dmaven.multiModuleProjectDirectory system property is not set. Check $M2_HOME environment variable and mvn script match.

    1.添加M2_HOME的环境变量 2.Preference->Java->Installed JREs->Edit 选择一个jdk, 添加  -Dmaven.multiModuleP ...

  10. Unit05 - 抽象类、接口和内部类(上)

    Unit05 - 抽象类.接口和内部类(上) 1.static final常量:  1)必须声明同时初始化  2)通过类名来访问,不能被改变  3)建议:常量名所有字母都大写(多个单词间用_)  4) ...