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 相关文章推荐
jQuery UI-Draggable 参数集合
Jan 10 Javascript
JQuery.uploadify 上传文件插件的使用详解 for ASP.NET
Jan 22 Javascript
根据身份证号自动输出相关信息(籍贯,出身日期,性别)
Nov 15 Javascript
分步解析JavaScript实现tab选项卡自动切换功能
Jan 25 Javascript
javascript学习指南之回调问题
Apr 23 Javascript
JavaScript 身份证号有效验证详解及实例代码
Oct 20 Javascript
vue实现裁切图片同时实现放大、缩小、旋转功能
Mar 02 Javascript
详解如何解决Vue和vue-template-compiler版本之间的问题
Sep 17 Javascript
详解Webstorm 下的Angular2.0开发之路(图文)
Dec 06 Javascript
解决在layer.open中使用时间控件laydate失败的问题
Sep 11 Javascript
JavaScript Array对象使用方法解析
Sep 24 Javascript
vue-cli3.X快速创建项目的方法步骤
Nov 14 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
phpmyadmin的#1251问题
2006/11/25 PHP
Yii的CDbCriteria查询条件用法实例
2014/12/04 PHP
php计算整个目录大小的方法
2015/06/19 PHP
php二维码生成以及下载实现
2017/09/28 PHP
javascript客户端解决方案 缓存提供程序
2010/07/14 Javascript
jquery的相对父元素和相对文档定位示例代码
2013/08/02 Javascript
JS 如何获取radio选中后的值及不选择取radio的值
2013/10/28 Javascript
20条学习javascript的编程规范的建议
2014/11/28 Javascript
借助FileReader实现将文件编码为Base64后通过AJAX上传
2015/12/24 Javascript
Javascript简写条件语句(推荐)
2016/06/12 Javascript
javascript添加前置0(补零)的几种方法
2017/01/05 Javascript
JavaScript实现跟随滚动缓冲运动广告框
2017/07/15 Javascript
vue2.0 资源文件assets和static的区别详解
2018/04/08 Javascript
js html实现计算器功能
2018/11/13 Javascript
小程序封装wx.request请求并创建接口管理文件的实现
2019/04/29 Javascript
Vue.extend 登录注册模态框的实现
2020/12/29 Vue.js
[46:25]DOTA2上海特级锦标赛主赛事日 - 4 败者组第五轮 MVP.Phx VS EG第二局
2016/03/05 DOTA
[03:03]DOTA2 2017国际邀请赛开幕战队入场仪式
2017/08/09 DOTA
[40:56]2018DOTA2亚洲邀请赛 3.31 小组赛 A组 Liquid vs TNC
2018/04/01 DOTA
python每次处理固定个数的字符的方法总结
2013/01/29 Python
pygame学习笔记(2):画点的三种方法和动画实例
2015/04/15 Python
用Python的Django框架编写从Google Adsense中获得报表的应用
2015/04/17 Python
详解Python中的strftime()方法的使用
2015/05/22 Python
浅谈使用Python变量时要避免的3个错误
2017/10/30 Python
解决python3中解压zip文件是文件名乱码的问题
2018/03/22 Python
Python列表解析配合if else的方法
2018/06/23 Python
python调用c++传递数组的实例
2019/02/13 Python
python入门教程之基本算术运算符
2020/11/13 Python
Django框架实现在线考试系统的示例代码
2020/11/30 Python
浅谈盘点5种基于Python生成的个性化语音方法
2021/02/05 Python
详解Css3新特性应用之过渡与动画
2017/01/10 HTML / CSS
英国最大的婴儿监视器网上商店:Baby Monitors Direct
2018/04/24 全球购物
斯洛伐克最大的婴儿食品和用品网上商店:Feedo.sk
2020/12/21 全球购物
竞选大队委员演讲稿
2014/04/28 职场文书
安全生产感想
2015/08/07 职场文书
寒假生活随笔
2015/08/15 职场文书