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 相关文章推荐
如何在Mozilla Gecko 用Javascript加载XSL
Jan 09 Javascript
css把超出的部分显示为省略号的方法兼容火狐
Jul 23 Javascript
分享28款免费实用的 JQuery 图片和内容滑块插件
Dec 15 Javascript
使用jquery制作弹出框效果
Apr 03 Javascript
javascript实现下拉提示选择框
Dec 29 Javascript
JS hashMap实例详解
May 26 Javascript
使用Bootstrap框架制作查询页面的界面实例代码
May 27 Javascript
jQuery自动或手动图片切换效果
Oct 11 jQuery
基于vue实现分页效果
Nov 06 Javascript
AngularJs点击状态值改变背景色的实例
Dec 18 Javascript
浅析vue中常见循环遍历指令的使用 v-for
Apr 18 Javascript
js实现前面自动补全位数的方法
Oct 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
比特率,大家看看这个就不用收音机音质去比MP3音质了
2021/03/01 无线电
PHP二分查找算法示例【递归与非递归方法】
2016/09/29 PHP
PHP实现将多个文件中的内容合并为新文件的方法示例
2017/06/10 PHP
PHP正则匹配到2个字符串之间的内容方法
2018/12/24 PHP
限制复选框的最大可选数
2006/07/01 Javascript
一个原生的用户等级的进度条
2010/07/03 Javascript
js 第二代身份证号码的验证机制代码
2011/05/12 Javascript
浅析JavaScript中的同名标识符优先级
2013/12/06 Javascript
jQuery使用hide方法隐藏页面上指定元素的方法
2015/03/30 Javascript
JavaScript中的Object对象学习教程
2016/05/20 Javascript
微信小程序 定位到当前城市实现实例代码
2017/02/23 Javascript
Vue之Watcher源码解析(1)
2017/07/19 Javascript
javaScript实现复选框全选反选事件详解
2020/11/20 Javascript
nodejs对项目下所有空文件夹创建gitkeep的方法
2019/08/02 NodeJs
express中static中间件的具体使用方法
2019/10/17 Javascript
JS highcharts实现动态曲线代码示例
2020/10/16 Javascript
使用k8s部署Django项目的方法步骤
2019/01/14 Python
Pytorch 使用不同版本的cuda的方法步骤
2020/04/02 Python
Python就将所有的英文单词首字母变成大写
2021/02/12 Python
传统HTML页面实现模块化加载的方法
2018/10/15 HTML / CSS
html5 canvas实现给图片添加平铺水印
2019/08/20 HTML / CSS
韩国爱茉莉太平洋化妆品美国站:Amore Pacific US
2016/10/28 全球购物
加拿大最大的钻石商店:Peoples Jewellers
2018/01/01 全球购物
最新的小工具和卓越的产品设计:Oh That Tech!
2019/08/07 全球购物
俄罗斯香水和化妆品网上商店:NOTINO.ru
2019/12/17 全球购物
简述数组与指针的区别
2014/01/02 面试题
求职者简历中的自我评价
2013/10/20 职场文书
出纳岗位职责范本
2013/12/01 职场文书
写好自荐信的几个要点
2013/12/26 职场文书
小学优秀辅导员事迹材料
2014/05/11 职场文书
刑事代理授权委托书
2014/09/17 职场文书
领导干部四风问题自我剖析材料
2014/09/25 职场文书
投资申请报告
2015/05/19 职场文书
医学生自荐信范文(2016精选篇)
2016/01/28 职场文书
HDFS免重启挂载新磁盘
2022/04/06 Servers
SQL Server中搜索特定的对象
2022/05/25 SQL Server