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 相关文章推荐
关于firefox的ElementTraversal 接口 使用说明
Nov 11 Javascript
基于jQuery的Tab选项框效果代码(插件)
Mar 01 Javascript
分享14个很酷的jQuery导航菜单插件
Apr 25 Javascript
jquery中live()方法和bind()方法区别分析
Jun 23 Javascript
微信小程序 欢迎页面的制作(源码下载)
Jan 09 Javascript
老生常谈js中0到底是 true 还是 false
Mar 08 Javascript
js 将canvas生成图片保存,或直接保存一张图片的实现方法
Jan 02 Javascript
详解tween.js 中文使用指南
Jan 05 Javascript
Vue瀑布流插件的使用示例
Sep 19 Javascript
jquery实现直播弹幕效果
Nov 28 jQuery
JavaScript设计模式之门面模式原理与实现方法分析
Mar 09 Javascript
关于vue的列表图片选中打钩操作
Sep 09 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
全国FM电台频率大全 - 26 西藏自治区
2020/03/11 无线电
颠覆常识!无色透明的咖啡诞生了(中日双语)
2021/03/03 咖啡文化
PHP下几种删除目录的方法总结
2007/08/19 PHP
php 生成自动创建文件夹并上传文件的示例代码
2014/03/07 PHP
PHP写日志的实现方法
2014/11/05 PHP
ThinkPHP项目分组配置方法分析
2016/03/23 PHP
PHP排序二叉树基本功能实现方法示例
2018/05/26 PHP
javascript面向对象包装类Class封装类库剖析
2013/01/24 Javascript
Jquery 模拟用户点击超链接或者按钮的方法
2013/10/25 Javascript
JavaScript中的this,call,apply使用及区别详解
2016/01/29 Javascript
利用Mongoose让JSON数据直接插入或更新到MongoDB
2017/05/03 Javascript
Js自定义多选框效果的实例代码
2017/07/05 Javascript
Angular父组件调用子组件的方法
2018/04/02 Javascript
vuex state及mapState的基础用法详解
2018/04/19 Javascript
浅谈在vue中使用mint-ui swipe遇到的问题
2018/09/27 Javascript
jQuery编写QQ简易聊天框
2020/08/27 jQuery
Vant+postcss-pxtorem 实现浏览器适配功能
2021/02/05 Javascript
python连接mysql调用存储过程示例
2014/03/05 Python
一个超级简单的python web程序
2014/09/11 Python
Windows8下安装Python的BeautifulSoup
2015/01/22 Python
python 脚本生成随机 字母 + 数字密码功能
2018/05/26 Python
Django QuerySet查询集原理及代码实例
2020/06/13 Python
pycharm 复制代码出现空格的解决方式
2021/01/15 Python
HTML5无刷新改变当前url的代码
2017/03/15 HTML / CSS
智能旅行箱:Horizn Studios
2018/04/30 全球购物
会计学应届毕业生推荐信
2013/11/04 职场文书
物流仓管员岗位职责
2013/12/04 职场文书
年度评优评先方案
2014/06/03 职场文书
会议欢迎词
2015/01/23 职场文书
公司财务部岗位职责
2015/04/14 职场文书
给朋友的道歉短信
2015/05/12 职场文书
党员心得体会范文2016
2016/01/23 职场文书
大学生党员暑假实践(活动总结)
2019/08/21 职场文书
详解python网络进程
2021/06/15 Python
浅谈Web Storage API的使用
2021/06/23 Javascript
JS的深浅复制详细
2021/10/16 Javascript