Request 接收参数乱码原理解析二:浏览器端编码原理
上一篇《Request 接收参数乱码原理解析一:服务器端解码原理》,分析了服务器端解码的过程,那么浏览器是根据什么编码的呢?
1. 浏览器解码
浏览器根据服务器页面响应Header中的“Content-Type: text/html; charset=gb2312”解码。修改web.config中“responseEncoding=utf-8”,发现服务器页面响应Header变成了“Content-Type: text/html; charset=utf8”。
<system.web>
<globalization requestEncoding="gb2312" responseEncoding="gb2312"/>
</system.web>

除了web.config中的globalization结点可以影响charset,修改页面Page_Load(配置文件仍为gb2312),发现页面charset输出也变成了utf-8,但同时也发现页面中的中文成了乱码。微软对Response.Charset的解释是获取或设置输出流的HTTP字符集,为什么会出现乱码?个人猜测可能整个页面是按照web.config中指定GB2312编码的,但输出的时候将字符集强制变成了utf-8。
protected void Page_Load(object sender, EventArgs e)
{
Response.Charset = "utf-8";
}
2. 提交表单时的编码
页面Get或者Post提交form表单数据时,会对表单中的中文进行编码,而编码方式是由服务器页面响应Header中的“Content-Type: text/html; charset=gb2312”确定的(和浏览器解码方式一致)。示例代码:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="EncodeTest.aspx.cs" Inherits="Com.Shizi.Time8.UI.Test.WebTest.EncodeTest" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>页面编码测试</title>
<script type="text/javascript" src="Scripts/jquery-2.1.1.min.js"></script>
</head>
<body>
<form id="form1" action="EncodeTest.aspx" method="post">
<div>
<input type="text" name="name" id="name" value="北京" />
</div>
<div>
<input type="submit" name="btnSumbit" value="sumbmit" /></div>
</form>
<div>
<input type="button" name="btnAjaxPost" value="AJaxPost提交" onclick="AjaxPost()" />
<input type="button" name="btnAjaxGet" value="AJaxGet提交" onclick="AjaxGet()" /></div>
<div id="divMessage" style="color:red"></div>
<script type="text/javascript">
function AjaxGet() {
$.ajax({
type: "GET",
url: "EncodeTest.aspx?namequery=" + $("#name").val(),
data: { name: $("#name").val(), action: "ajax", methodtype: "get" },
success: function (data) {
$("#divMessage").html(data);
}
});
}
function AjaxPost() {
$.ajax({
type: "POST",
url: "EncodeTest.aspx?namequery=" + $("#name").val(),
data: { name: $("#name").val(), action: "ajax", methodtype: "post" },
success: function (data) {
$("#divMessage").text(data);
}
});
} </script>
</body>
</html>
EncodeTest.aspx代码
不管get提交还是post提交,input控件全部都进行了GB2312编码,提交的数据为“name=%B1%B1%BE%A9&btnSumbit=sumbmit”。修改web.config中“responseEncoding=utf-8”,发现服务器页面响应Header中的“Content-Type: text/html; charset=utf8”,再次提交表单时编码已经成了utf-8,内容变为“name=%E5%8C%97%E4%BA%AC&btnSumbit=sumbmit”。
观察发现,不管get提交还是post提交,HTTP请求中并没有指定服务器端的解码方式,服务器端解码还是根据服务器配置获取的,本例中是用GB2312解码的。

3. 浏览器地址栏Url编码
在浏览器中输入地址:http://localhost:52443/EncodeTest.aspx?name=北京,“name=北京”的编码方式随浏览器不同而不同,IE11编码方式为GBK,服务器用GB2312解码正确;Firefox34.0编码方式为utf-8,服务器GB2312解码乱码。URL中的编码依赖于浏览器,开发中不建议使用,一些地址链接含有中文时,建议在生成链接时,对中文指定编码方式编码。
4. JQuery中的AJax提交
JQuery是一款优秀的js框架,被广泛使用,但通过AJax提交数据时,却容易出现乱码。通过测试和分析JQuery源码,AJax请求时,推荐方式为:
1)POST请求:参数放到data中,无需对参数值编码,JQuery在构造HTTP请求时,会调用js的函数encodeURIComponent()对data中的键值对分别进行utf-8编码,服务器用utf-8解码。url中对应的就是url地址,不能含有参数。
即使服务器Globalization结点配置的GB2312解码,Request.Form["xxx"]也会用utf-8解码,因为AJax的post请求中在HTTP头添加了代码“Content-Type: text/html; charset=utf8”,告诉服务器用utf-8解码,达到编码和解码一致的目的。这点可能和我们平时想的不一样,整站配置为GB2312编码的站点,竟然AJax的post请求都是用的utf-8编码!
// 拼装参数
if ( s.data && s.processData && typeof s.data !== "string" ) {
s.data = jQuery.param( s.data, s.traditional );
} // 如果有post data的话,设置请求Header
if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
jqXHR.setRequestHeader( "Content-Type", s.contentType );
} // key/values into a query string
jQuery.param = function( a, traditional ) {
var prefix,
s = [],
add = function( key, value ) {
// If value is a function, invoke it and return its value
value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
}; // Set traditional to true for jQuery <= 1.3.2 behavior.
if ( traditional === undefined ) {
traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
} // If an array was passed in, assume that it is an array of form elements.
if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
// Serialize the form elements
jQuery.each( a, function() {
add( this.name, this.value );
}); } else {
// If traditional, encode the "old" way (the way 1.3.2 or older
// did it), otherwise encode params recursively.
for ( prefix in a ) {
buildParams( prefix, a[ prefix ], traditional, add );
}
} // Return the resulting serialization
return s.join( "&" ).replace( r20, "+" );
};
JQuery AJax核心代码
2)GET请求:参数放在Url中,并按照和服务器一致的编码方式编码,如服务器配置的Globalization结点为UTF-8,则将参数值用UTF-8编码,可以调用函数encodeURIComponent();如果服务器配置为GB2312,则将参数用GB2312编码,可以调用escape()。Get和Post请求的一大差别是,GET请求不会改变请求的Header,Request.QueyString["xxx"]解码用的是Globalization指定的编码。
如下面的代码,在配置为GB2312编码的站点运行正常,无乱码,其中post请求是utf-8解码,get请求是gb2312解码。
function AjaxGet() {
$.ajax({
type: "GET",
url: "EncodeTest.aspx?namequery=" + escape($("#name").val()),
success: function (data) {
$("#divMessage").html(data);
}
});
}
function AjaxPost() {
$.ajax({
type: "POST",
url: "EncodeTest.aspx",
data: { name: $("#name").val(), action: "ajax", methodtype: "post" },
success: function (data) {
$("#divMessage").text(data);
}
});
}
默认情况下,JQuery的AJax方法通过post提交数据,编码都是用的utf-8,通过Header指定服务器解码方式也为utf-8,但某些特殊情况下可能想服务器用gb2312解码(现在想来应该不需要这种场景,因为本身就不大合理,当时可能在某些不大合理的前提下确实需要来着,还不停的百度),网上查找资料是说AJax时,添加属性“contentType: "application/x-www-form-urlencoded; charset=utf-8",”个人测试IE下生效了,服务器变成了GB2312解码,但火狐下未生效,原因未知,单步跟踪了代码都执行了,没啥问题。
参考:Asp.net中Response.Charset 与Response.ContentEncoding区别,charset 和character encoding,深入浅出URL编码。
Request 接收参数乱码原理解析二:浏览器端编码原理的更多相关文章
- Request 接收参数乱码原理解析三:实例分析
通过前面两篇<Request 接收参数乱码原理解析一:服务器端解码原理>和<Request 接收参数乱码原理解析二:浏览器端编码原理>,了解了服务器和浏览器编码解码的原理,接下 ...
- Request 接收参数乱码原理解析一:服务器端解码原理
“Server.UrlDecode(Server.UrlEncode("北京")) == “北京””,先用UrlEncode编码然后用UrlDecode解码,这条语句永远为true ...
- Request 接收参数乱码原理解析
起因: 今天早上被同事问了一个问题:说接收到的参数是乱码,让我帮着解决一下. 实际情景: 同事负责的平台是Ext.js框架搭建的,web.config配置文件里配置了全局为“GB2312”编码: &l ...
- 详细解析ASP.NET中Request接收参数乱码原理
起因:今天早上被同事问了一个问题:说接收到的参数是乱码,让我帮着解决一下. 实际情景: 同事负责的平台是Ext.js框架搭建的,web.config配置文件里配置了全局为“GB2312”编码: < ...
- 处理request接收参数的中文乱码的问题:
Ø POST的解决方案: * POST的参数在请求体中,直接到达后台的Servlet.数据封装到Servlet中的request中.request也有一个缓冲区.request的缓冲区也是ISO-88 ...
- laravel 请求request 接收参数
获取请求输入 获取所有输入值 你可以使用 all 方法以数组格式获取所有输入值: $input = $request->all(); 获取单个输入值 使用一些简单的方法,就可以从 Illumin ...
- tomcat原理解析(二):整体架构
一 整体结构 前面tomcat实现原理(一)里面描述了整个tomcat接受一个http请求的简单处理,这里面我们讲下整个tomcat的架构,以便对整体结构有宏观的了解.tomat里面由很多个容器结合在 ...
- Java多线程系列 JUC线程池03 线程池原理解析(二)
转载 http://www.cnblogs.com/skywang12345/p/3509954.html http://www.cnblogs.com/skywang12345/p/351294 ...
- 对小程序的网络请求的封装 wx.request 接收参数修改
wepy-mall/wxRequest.js at master · dyq086/wepy-mall https://github.com/dyq086/wepy-mall/blob/master/ ...
随机推荐
- JavaScript 基础第一天
一.前言 如果将前端比喻成一人,那么Html就是这个人的骨骼脉络,CSS则是这个人的身上的装饰,JavaScript则是这个人的行为.作为一种脚本语言JavasSript具有着弱类型等特点.(在这里我 ...
- Android JIT实时编译器的设置
在Android JIT实时编译是在Android 2.2之后才引入的,JIT编译器可以显著的提高机器的性能,经过测试,android 2.2的性能较android 2.1提高了 2-5倍.JIT提 ...
- NSString格式校验
在项目开发过程中,NSString类型的变量是经常用到的,而且我们常常会对其格式进行对应的各种校验,你比如,在登录注册的时候,需要验证用户名的长度,用户名的字符组成等等,其实现在也有很多第三方提供的N ...
- nginx+winsw windows服务
1.下载Nginx:http://nginx.org/en/download.html 2.下载winsw配置包:http://files.cnblogs.com/files/objecttozero ...
- 使用 Productivity Power Tools 高级扩展 来帮助你提高 VS2012 的工作效率
Productivity Power Tools 高级工具是帮助开发者提高工作效率的, 用于 Visual Studio 2012 专业版(及以上) 的一组免费扩展. 本文大多数内容译自MSDN:ht ...
- 可在广域网部署运行的QQ高仿版 -- GG叽叽V3.4,增加系统设置、最近联系人、群功能(源码)
自从上次版本(GG叽叽V3.2,增加离线消息.离线文件功能)发布后,我个人觉得主要的大功能都实现得差不多了,接下来的几个版本将不断优化GG的细节,提高其可用性.这次版本更新的内容主要是为GG增加了系统 ...
- Java虚拟机1:什么是Java
前言 让我们来看一下Java的广告词,来自http://www.java.com/zh_CN/about/: 97%的企业桌面运行Java 美国有89%的桌面(或计算机)运行Java 全球有900万J ...
- 设计模式之美:Extension Object(扩展对象)
索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):使用示例结构实现 Extension Object. 实现方式(二):使用泛型实现 IExtensibleObject<T ...
- Silverlight无法启动调试,错误“Unable to start debugging. The Silverlight Developer Runtime is not installed. Please install a matching version.” 解决办法
今天调试Silverlight出现了以下错误: 意思是“无法启动调试,因为Silverlight Developer Runtime没有安装,请安装一个匹配的版本”.但是按Ctrl + F5可以调试运 ...
- java笔试题(金山网络)
今天参加金山的校园招聘,java笔试,回来仔细研究实现一下: 题目1:工厂两条生产线,三个工人,生产线上可以最多存放m个产品,当生产线满时,机器停止生产,等产品线不满时才继续生产,每条产线上一次只能允 ...