日期:2014-05-16  浏览次数:20382 次

IE9下面的Jsonp规范

昨天网站突然出现问题,导致IE9下面,很多Jsonp的内容出不来,经分析原因如下:
1. 原来的JSONP返回的Content-Type不符合规范,因此Jsonp请求出现了被IE9 block掉的情况;
2. 在IE9中,如果在Jsonp请求中,http response header中有X-Content-Type-Options: nosniff并且Content-Type: text/html; charset=GBK那么这个请求的内容不会被 IE9 当成 javascript 执行。而Jsonp请求的原理,就是要把返回内容直接当做javascript脚本,直接运行掉才会起效。

解决办法:
1、按照规范,Jsonp请求实际上应该返回Content-Type: text/javascript; charset=GBK如果修改Content-Type为text/javascript ,可以解决此问题。一般代码中都是默认为text/html;,因此需要改为text/javascript;
2、去掉X- Content-Type-Options: nosniff,待修改接口的Content-Type后再加上(临时办法);

jsonp 请求和标准的 ajax json 请求的差别:
1. ajax请求是通过浏览器的XmlRequestHttp对象发出的异步请求,然后通过这个对象拿到服务器端返回的字符串,再进行 json的解析,转换成可以使用的数据。
2. jsonp请求算是对跨域ajax的一种hack,因为标准的ajax是不能跨域请求的。原理是往页面里面插入一个<script>标签,把返回的内容直接当成js立即执行掉。
3. 对于浏览器来说,jsonp请求和页面里的.js文件没有区别。而.js文件会被http服务器识别,Content-Type的值为text/javascript。但是jsonp请求,是后端提供的接口,后缀一般为.htm,.do。content-type还为text/html,这就造成了 IE9 block掉了这些请求。

识别 ajax 和 jsonp 接口的简单方法:
jsonp请求都是 GET 请求,请求参数里面有var,callback这两个参数名之一。
另外如果明确是提供给其他应用使用的接口,也就是需要被跨域使用,基本可以确定是jsonp。

jsonp请求在IE9下发出的请求是application/javascript,因为在IE9下的响应标头中看到有配置项:X-Content-Type-Options,内容为:nosniff,因此会产生“脚本因Mime类型不匹配而被组织”的信息。
IE9可以执行的mime-type(Script脚本):
"text/javascript", "application/javascript", "text/ecmascript", "application/ecmascript", "text/x-javascript", "application/x-javascript", "text/jscript", "text/vbscript", "text/vbs"
text/javascript与application/javascript的区别:
application/javascript: JavaScript; Defined in RFC 4329 but not accepted in IE 8 or earlier, however text/javascript is accepted.
text/javascript (Obsolete): JavaScript; Defined in and obsoleted by RFC 4329 in order to discourage its usage in favor of application/javascript. However,text/javascript is allowed in HTML 4 and 5 and, unlike application/javascript, has cross-browser support
上面说明,text/javascript已经过时,而application/javascript更加符合规范,但是IE8以前的版本不兼容application/javascript这个mime-type。所以还是建议使用text/javascript。

?