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 相关文章推荐
JS 控制CSS样式表
Aug 20 Javascript
CSS和Javascript简单复习资料
Jun 29 Javascript
浅析JavaScript中的typeof运算符
Nov 30 Javascript
jQuery实现可编辑的表格实例讲解(2)
Sep 17 Javascript
详谈jQuery.load()和Jsp的include的区别
Apr 12 jQuery
纯js实现的积木(div层)拖动功能示例
Jul 19 Javascript
详解如何用模块化的方式写vuejs
Dec 16 Javascript
jQuery Ajax实现Select多级关联动态绑定数据的实例代码
Oct 26 jQuery
关于layui 下拉列表的change事件详解
Sep 20 Javascript
微信小程序 scroll-view 水平滚动实现过程解析
Oct 12 Javascript
javascript实现弹幕墙效果
Nov 28 Javascript
基于JavaScript或jQuery实现网站夜间/高亮模式
May 30 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 判断访客是否为搜索引擎蜘蛛的函数代码
2011/07/29 PHP
php数组排序usort、uksort与sort函数用法
2014/11/17 PHP
简单解析PHP程序的运行流程
2016/06/23 PHP
无需数据库在线投票调查php代码
2016/07/20 PHP
php进程(线程)通信基础之System V共享内存简单实例分析
2019/11/09 PHP
发一个自己用JS写的实用看图工具实现代码
2008/07/26 Javascript
浅析基于WEB前端页面的页面内容搜索的实现思路
2014/06/10 Javascript
在NodeJS中启用ECMAScript 6小结(windos以及Linux)
2014/07/15 NodeJs
JS实现一个列表中包含上移下移删除等功能
2014/09/24 Javascript
JavaScript编程的单例设计模讲解
2015/11/10 Javascript
Bootstrap3制作自己的导航栏
2016/05/12 Javascript
Javascript 对cookie操作详解及实例
2016/12/29 Javascript
JS中的事件委托实例浅析
2018/03/22 Javascript
详解Vue 全局引入bass.scss 处理方案
2018/03/26 Javascript
Vue脚手架的简单使用实例
2018/07/10 Javascript
使用webpack编译es6代码的方法步骤
2019/04/28 Javascript
JS获取动态添加元素的方法详解
2019/07/31 Javascript
对vue生命周期的深入理解
2020/12/03 Vue.js
python将多个文本文件合并为一个文本的代码(便于搜索)
2011/03/13 Python
谈谈Python进行验证码识别的一些想法
2016/01/25 Python
Python 自动刷博客浏览量实例代码
2017/06/14 Python
Python3.6.0+opencv3.3.0人脸检测示例
2018/05/25 Python
Python实现对特定列表进行从小到大排序操作示例
2019/02/11 Python
python打印直角三角形与等腰三角形实例代码
2019/10/20 Python
python基于三阶贝塞尔曲线的数据平滑算法
2019/12/27 Python
关于tf.nn.dynamic_rnn返回值详解
2020/01/20 Python
如何通过python实现全排列
2020/02/11 Python
python GUI库图形界面开发之PyQt5多行文本框控件QTextEdit详细使用方法实例
2020/02/28 Python
Keras: model实现固定部分layer,训练部分layer操作
2020/06/28 Python
Python如何输出百分比
2020/07/31 Python
HTML5+CSS3应用详解
2014/02/24 HTML / CSS
网上签名寄语活动留言
2014/01/18 职场文书
阳光体育活动方案
2014/02/16 职场文书
详解redis在微服务领域的贡献
2021/10/16 Redis
PostgreSQL事务回卷实战案例详析
2022/03/25 PostgreSQL
深入解析Apache Hudi内核文件标记机制
2022/03/31 Servers