javascript跨域原因以及解决方案分享


Posted in Javascript onApril 08, 2015

产生跨域问题的原因

跨域问题是浏览器同源策略限制,当前域名的js只能读取同域下的窗口属性。

跨域问题产生的场景

当要在在页面中使用js获取其他网站的数据时,就会产生跨域问题,比如在网站中使用ajax请求其他网站的天气、快递或者其他数据接口时以及hybrid app中请求数据,浏览器就会提示以下错误。这种场景下就要解决js的跨域问题。

XMLHttpRequest cannot load http://你请求的域名. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://当前页的域名' is therefore not allowed access.

哪些情况会产生跨域问题

一个网站的网址组成包括协议名,子域名,主域名,端口号。比如 https://github.com/ ,其中https是协议名,www是子域名,github是主域名,端口号是80,当在在页面中从一个url请求数据时,如果这个url的协议名、子域名、主域名、端口号任意一个有一个不同,就会产生跨域问题。
即使是在 http://localhost:80/ 页面请求 http://127.0.0.1:80/ 也会有跨域问题

解决跨域问题

解决跨域问题有以下一种方式

使用jsonp
服务端代理
服务端设置Request Header头中Access-Control-Allow-Origin为指定可获取数据的域名

jsonp的解决方式

json≠jsonp

原理

jsonp解决跨域问题的原理是,浏览器的script标签是不受同源策略限制(你可以在你的网页中设置script的src属性问cdn服务器中静态文件的路径)。那么就可以使用script标签从服务器获取数据,请求时添加一个参数为callbakc=?,?号时你要执行的回调方法。

前端实现

以jQuery2.1.3的ajax方法为例

$.ajax({

    url:"",

    dataType:"jsonp",

    data:{

        params:""

        }

}).done(function(data){

    //dosomething..

})

仅仅是客户端使用jsonp请求数据是不行的,因为jsonp的请求是放在script标签中的,和普通请求不同的地方在于,它请求到的是一段js代码,如果服务端返回了json字符串,那么浏览器就会报错。所以jsonp返回数据需要服务端做一些处理。

服务端返回数据处理

上面说了jsonp的原理是利用script标签来解决跨域,但是script标签是用来获取js代码的,那么我们怎么获取到请求的数据呢。

这就需要服务端做一些判断,当参数中带有callback属性时,返回的type要为application/javascript,把数据作为callback的参数执行。下面是jsonp返回的数据的格式示例

/**/ typeof jQuery21307270454438403249_1428044213638 === 'function' && jQuery21307270454438403249_1428044213638({"code":1,"msg":"success","data":{"test":"test"}});

这是express4.12.3关于jsonp的实现代码

// jsonp
 if (typeof callback === 'string' && callback.length !== 0) {
 this.charset = 'utf-8';
 this.set('X-Content-Type-Options', 'nosniff');
 this.set('Content-Type', 'text/javascript');

 // restrict callback charset
 callback = callback.replace(/[^\[\]\w$.]/g, '');

 // replace chars not allowed in JavaScript that are in JSON
 body = body
  .replace(/\u2028/g, '\\u2028')
  .replace(/\u2029/g, '\\u2029');

 // the /**/ is a specific security mitigation for "Rosetta Flash JSONP abuse"
 // the typeof check is just to reduce client error noise
 body = '/**/ typeof ' + callback + ' === \'function\' && ' + callback + '(' + body + ');';
 }

服务端设置Access-Control-Allow-Origin

这种方式只要服务端把response的header头中设置Access-Control-Allow-Origin为制定可请求当前域名下数据的域名即可。一般情况下设为即可。这样客户端就不需要使用jsonp来获取数据。
关于Access-Control-Allow-Origin设为是否会有安全问题,知乎上有个讨论。

http://www.zhihu.com/question/22992229

浏览器支持

Access-Control-Allow-Origin是html5新增的一项标准,IE10以下是不支持的,所以如果产品面向的是PC端,就要使用服务端代理或jsonp。

以上所述就是本文的全部内容了,希望能够对大家学习javascript跨域有所帮助。

Javascript 相关文章推荐
经常用的图片在容器中的水平垂直居中实例
Jun 10 Javascript
11款新鲜的jQuery插件[附所有demo下载]
Jan 24 Javascript
jquery ajax中使用jsonp的限制解决方法
Nov 22 Javascript
基于JavaScript实现图片点击弹出窗口而不是保存
Feb 06 Javascript
原生js实现对Ajax的封装(仿jquery)
Jan 22 Javascript
requirejs + vue 项目搭建详解
Jun 16 Javascript
Vue 中的compile操作方法
Feb 26 Javascript
node thread.sleep实现示例
Jun 20 Javascript
axios简单实现小程序延时loading指示
Jul 30 Javascript
记一次Vue.js混入mixin的使用(分权限管理页面)
Apr 17 Javascript
vue项目前端错误收集之sentry教程详解
May 27 Javascript
JS实现省市县三级下拉联动
Apr 10 Javascript
JavaScript 里的类数组对象
Apr 08 #Javascript
cookie的secure属性详解
Apr 08 #Javascript
jQuery简单tab切换效果实现方法
Apr 08 #Javascript
JavaScript中的普通函数与构造函数比较
Apr 07 #Javascript
jQuery控制cookie过期时间的方法
Apr 07 #Javascript
JavaScript随机生成信用卡卡号的方法
Apr 07 #Javascript
JavaScript实现信用卡校验方法
Apr 07 #Javascript
You might like
JavaScript让IE浏览器event对象符合W3C DOM标准
2009/11/24 Javascript
document.getElementById获取控件对象为空的解决方法
2013/11/20 Javascript
在javascript中实现函数数组的方法
2013/12/25 Javascript
node.js中的fs.truncate方法使用说明
2014/12/15 Javascript
使用javascript插入样式
2016/03/14 Javascript
实践中学习AngularJS表单
2016/03/21 Javascript
ionic实现可滑动的tab选项卡切换效果
2020/04/15 Javascript
jQuery实现动态添加和删除input框实例代码
2019/03/26 jQuery
vue 解决异步数据更新问题
2019/10/29 Javascript
JavaScript canvas绘制折线图
2020/02/18 Javascript
详解在IDEA中将Echarts引入web两种方式(使用js文件和maven的依赖导入)
2020/07/11 Javascript
详解Python中的元组与逻辑运算符
2015/10/13 Python
Python+django实现文件下载
2016/01/17 Python
Python的网络编程库Gevent的安装及使用技巧
2016/06/24 Python
numpy中实现二维数组按照某列、某行排序的方法
2018/04/04 Python
Python continue继续循环用法总结
2018/06/10 Python
python实现美团订单推送到测试环境,提供便利操作示例
2019/08/09 Python
python通过SSH登陆linux并操作的实现
2019/10/10 Python
Python实现直播推流效果
2019/11/26 Python
如何更改 pandas dataframe 中两列的位置
2019/12/27 Python
python实现Oracle查询分组的方法示例
2020/04/30 Python
Crocs美国官方网站:卡骆驰洞洞鞋
2017/08/04 全球购物
老板电器官方购物商城:老板油烟机、燃气灶、消毒柜、电烤箱
2018/05/30 全球购物
业务员岗位职责
2013/11/16 职场文书
酒店拾金不昧表扬信
2014/01/18 职场文书
《郑和远航》教学反思
2014/04/16 职场文书
医院院务公开实施方案
2014/05/03 职场文书
青春演讲稿范文
2014/05/08 职场文书
我的中国梦口号
2014/06/16 职场文书
中华在我心中演讲稿
2014/09/13 职场文书
通报表扬范文
2015/01/17 职场文书
2015年审计人员工作总结
2015/05/26 职场文书
生产车间管理制度
2015/08/04 职场文书
《水浒传》读后感3篇(范文)
2019/09/19 职场文书
MySQL选择合适的备份策略和备份工具
2022/06/01 MySQL
js前端图片加载异常兜底方案
2022/06/21 Javascript