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 指导方针
Apr 05 Javascript
javascript中声明函数的方法及调用函数的返回值
Jul 22 Javascript
js实现类似新浪微博首页内容渐显效果的方法
Apr 10 Javascript
JavaScript从0开始构思表情插件
Jul 26 Javascript
jQuery插件HighCharts绘制2D带有Legend的饼图效果示例【附demo源码下载】
Mar 10 Javascript
vue 实现 tomato timer(蕃茄钟)实例讲解
Jul 24 Javascript
Angular4集成ng2-file-upload的上传组件
Mar 14 Javascript
webpack4之SplitChunksPlugin使用指南
Jun 12 Javascript
vue+element的表格实现批量删除功能示例代码
Aug 17 Javascript
新年快乐! javascript实现超级炫酷的3D烟花特效
Jan 30 Javascript
js实现多个倒计时并行 js拼团倒计时
Feb 25 Javascript
解决layer.confirm选择完之后消息框不消失的问题
Sep 16 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
自动跳转中英文页面
2006/10/09 PHP
首页四格,首页五格For6.0(GBK)(UTF-8)[12种组合][9-18][版主安装测试通过]
2007/09/24 PHP
实用函数5
2007/11/08 PHP
PHP的时间戳与具体时间转化的简单实现
2016/06/13 PHP
thinkphp Apache配置重启Apache1 restart 出错解决办法
2017/02/15 PHP
PHP实现单文件、多个单文件、多文件上传函数的封装示例
2019/09/02 PHP
实现连缀调用的map方法(prototype)
2009/08/05 Javascript
关于javascript中的parseInt使用技巧
2009/09/03 Javascript
使用PHP+JQuery+Ajax分页的实现
2013/04/23 Javascript
javascript中数组的sort()方法的使用介绍
2013/12/18 Javascript
使用jQuery重置(reset)表单的方法
2014/05/05 Javascript
jquery.idTabs 选项卡使用示例代码
2014/09/03 Javascript
jQuery模拟物体自由落体运动(附演示与demo源码下载)
2016/01/21 Javascript
基于HTML5上使用iScroll实现下拉刷新,上拉加载更多
2016/05/21 Javascript
简单实现js倒计时功能
2017/02/13 Javascript
利用C/C++编写node.js原生模块的方法教程
2017/07/07 Javascript
Vue2 配置 Axios api 接口调用文件的方法
2017/11/13 Javascript
JavaScript作用域链实例详解
2019/01/21 Javascript
vue Treeselect 树形下拉框:获取选中节点的ids和lables操作
2020/08/15 Javascript
使用python在本地电脑上快速处理数据
2017/06/22 Python
用Python下载一个网页保存为本地的HTML文件实例
2018/05/21 Python
wxPython的安装与使用教程
2018/08/31 Python
详解Python3序列赋值、序列解包
2019/05/14 Python
python实现对象列表根据某个属性排序的方法详解
2019/06/11 Python
Python Django Vue 项目创建过程详解
2019/07/29 Python
python根据多个文件名批量查找文件
2019/08/13 Python
python通过实例讲解反射机制
2019/10/17 Python
解决pycharm最左侧Tool Buttons显示不全的问题
2019/12/17 Python
python中adb有什么功能
2020/06/07 Python
世界上最好的威士忌和烈性酒购买网站:The Whisky Exchange
2016/11/20 全球购物
Parts Express:音频、视频和扬声器的第一来源
2017/04/25 全球购物
Willer台湾:日本高速巴士/夜行巴士预约
2017/07/09 全球购物
暑假学习心得体会
2014/09/02 职场文书
报表员工作失误检讨书范文
2014/09/19 职场文书
股份转让协议书范本
2015/01/27 职场文书
暑假生活随笔
2015/08/15 职场文书