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 相关文章推荐
JavaScript delete 属性的使用
Oct 08 Javascript
使用jQuery.Validate进行客户端验证(初级篇) 不使用微软验证控件的理由
Jun 28 Javascript
JQuery页面图片切换和新闻列表滚动效果的具体实现
Sep 26 Javascript
jquery checkbox实现单选小例
Nov 27 Javascript
28个常用JavaScript方法集锦
Jan 14 Javascript
原生javascript实现解析XML文档与字符串
Mar 01 Javascript
json与jsonp知识小结(推荐)
Aug 16 Javascript
基于vue的下拉刷新指令和滚动刷新指令
Dec 23 Javascript
Jquery与Bootstrap实现后台管理页面增删改查功能示例
Jan 22 Javascript
vue-cli 默认路由再子路由选中下的选中状态问题及解决代码
Sep 06 Javascript
vue+elementUi 实现密码显示/隐藏+小图标变化功能
Jan 18 Javascript
Jquery高级应用Deferred对象原理及使用实例
May 28 jQuery
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
php面向对象全攻略 (七) 继承性
2009/09/30 PHP
php函数连续调用实例分析
2015/07/30 PHP
php生出随机字符串
2017/07/06 PHP
php生成静态页面并实现预览功能
2019/06/27 PHP
javascript第一课
2007/02/27 Javascript
dojo 之基础篇
2007/03/24 Javascript
基于jQuery的一个扩展form序列化到json对象
2010/12/09 Javascript
网页中可关闭的漂浮窗口实现可自行调节
2013/08/20 Javascript
js字符串截取函数substr substring slice使用对比
2013/11/27 Javascript
jQuery设置指定网页元素宽度和高度的方法
2015/03/25 Javascript
js实现当前输入框高亮显示的方法
2015/08/19 Javascript
javascript模拟C#格式化字符串
2015/08/26 Javascript
jquery实现具有嵌套功能的选项卡
2016/02/12 Javascript
在React框架中实现一些AngularJS中ng指令的例子
2016/03/06 Javascript
jQuery筛选数组之grep、each、inArray、map的用法及遍历json对象
2016/06/20 Javascript
webpack配置文件和常用配置项介绍
2017/04/28 Javascript
浅谈JavaScript闭包
2019/04/09 Javascript
仿iPhone通讯录制作小程序自定义选择组件的实现
2019/05/23 Javascript
python基础教程之元组操作使用详解
2014/03/25 Python
Python读取文件内容的三种常用方式及效率比较
2017/10/07 Python
Python网络编程详解
2017/10/31 Python
解决python写入mysql中datetime类型遇到的问题
2018/06/21 Python
django自带serializers序列化返回指定字段的方法
2019/08/21 Python
Python 项目转化为so文件实例
2019/12/23 Python
对tensorflow中cifar-10文档的Read操作详解
2020/02/10 Python
python利用递归方法实现求集合的幂集
2020/09/07 Python
教你一分钟在win10终端成功安装Pytorch的方法步骤
2021/01/28 Python
PHP如何调用MYSQL存储过程
2014/05/30 面试题
法雷奥SQA(electric)面试问题
2016/01/23 面试题
海南地接欢迎词
2014/01/14 职场文书
清明节网上祭英烈活动总结
2014/04/30 职场文书
交通事故协议书范文
2014/10/23 职场文书
承诺书范本
2015/01/21 职场文书
企业管理不到位检讨书
2019/06/27 职场文书
用Python爬取英雄联盟的皮肤详细示例
2021/12/06 Python
css中:last-child不生效的解决方法
2022/08/05 HTML / CSS