jsonp无X-Requested-With 及其深扒
来源:互联网 发布:js点击滑动到相应div 编辑:程序博客网 时间:2024/05/19 23:58
事件背景交代
事情的起因是:A和B站都得调A站的接口,然后前端把请求写成jsonp的,又因为js是在CDN上,A和B是公用相同的js。然后就出现了A站调接口出现前端无法解析的问题,B站调A站接口却正常。出现无法解析的问题是因为callback被包了两层,即callback(callback("result"))
问题分析
既然是返回的内容出现了问题,那就是后端的代码问题,二话不说看代码。看了好长时间,果然拦截器的代码写的有问题:有两个拦截器,
一个是调用接口类所在包的拦截器(局域拦截器),针对这个包下面的每一个请求判断是否jsonp,是jsonp就自动给返回内容包一层callback;
另外一个是全局的拦截器中,对每个请求都进行了判断,如果请求中带有callback参数且请求类型是ajax,那就自动给返回内容包上一层callback。
显然,A站调A站自己的接口,是符合两个拦截器的条件的,所以,返回内容被callback包了两次,出现了返回内容无法被解析的问题;而B站调A站接口却是只符合局域拦截器的,所以返回内容是正常的,可以被解析。
问题总结
这里总结一下,其实前端和后端代码都有问题:
前端代码有问题是A站调A站,怎么用jsonp呢(从技术的角度是可以实现的,但是,逻辑上是错误的),只需要普通的ajax即可;
后端的代码有问题是在判断请求是否jsonp的同时又判断请求类型是否ajax,这两个条件不可能同时满足的,因为jsonp不是ajax,虽然我们是通过jquery的ajax设置dataType为jsonp来实现jsonp的,但是,jsonp是普通的请求。
问题深扒
为什么jsonp是普通请求而不是ajax呢?这里说下,ajax请求是肯定带有X-Requested-With请求头的,而普通的请求是不会有X-Requested-With请求头,所以我们一般判断是ajax还是普通请求是通过这个X-Requested-With头来判断的。
正好有时间就深扒了下这个问题。因为浏览器受到同源策略限制,A源(域名)下的资源,只可以访问A源的接口,如果不做处理的话,A源访问B源的接口,会出现也就是我们所常说的跨域问题了。
处理跨域问题,有哪几种方案呢?一般来说,有三个方案
jsonp
jsonp是根据img和script等是通过src属性来下载资源的,而src的方式是不受跨域的影响的。jquery的jsonp是通过动态生成script标签带上参数和callback去向服务器请求资源,然后请求返回后,根据callback调用指定的方法,再把生成的script标签给删除。
两次请求的方式
第一次调自己的服务端的接口,第二次在服务端调“其他源”的接口(跨域是针对浏览器的,对服务器来说是没有什么跨域不跨域的)
CORS
假如A站要调B站的接口,在不做处理之前肯定是http 403的,要用CORS的方式,需要在B站写个过滤器/拦截器/甚至AOP,拦截请求,在每个请求中加上 response.setHeader("Access-Control-Allow-Origin", "*"); 表示该资源可以被任意的外域访问
参考:
http://www.cnblogs.com/digdeep/p/4170059.html
http://blog.csdn.net/puma_dong/article/details/51395976
- jsonp无X-Requested-With 及其深扒
- x-requested-with
- x-requested-with
- x-requested-with
- X-Requested-With
- x-requested-with 请求头
- Ajax之X-Requested-With请求头
- Ajax之X-Requested-With请求头
- "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
- x-requested-with请求头与Ajax
- X-Requested-With Http请求头含义
- web_add_auto_header("x-requested-with", "XMLHttpRequest "); 在LR中的作用
- Ajax 请求的http头信息特点 x-requested-with
- 从jQuery的ajax请求中删除X-Requested-With
- easyui form ajax提交 requet头里 没有X-Requested-With
- Ajax 请求的http头信息特点 x-requested-with
- x-requested-with 判断是否是Ajax异步请求
- HTTP之X-Requested-With分析和思考
- java后台封装json数据(一)
- validate中添加焦点事件、键盘事件
- 2016年12月16日
- 521. Longest Uncommon Subsequence I
- 10 条提升 Android 性能的建议
- jsonp无X-Requested-With 及其深扒
- Node.js异步操作和CMD命令行下创建文件
- 获取当前文件夹的名字
- 为什么使用 NoSQL:NoSQL 与 SQL 的区别
- IntentService详解
- 卸载 Cloudera Manager 5.1.x.和 相关软件【官网翻译:高可用】
- java学习笔记(常量 二进制 其他进制 负数进制 变量 自动类型提升 强制类型转换 )
- CCNA第一天
- 单例设计模式及反射机制破坏