javascript跨域原因以及解决方案分享
作者:hebedich 时间:2024-04-10 10:44:32
产生跨域问题的原因
跨域问题是浏览器同源策略限制,当前域名的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跨域有所帮助。
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
python如何读取.mtx文件
JQuery中serialize()用法实例分析
形成视觉冲击的几种方式
![](https://img.aspxhome.com/file/UploadPic/20088/3/200883164413717s.jpg)
python统计RGB图片某像素的个数案例
![](https://img.aspxhome.com/file/2023/3/77683_0s.jpg)
python 中关于pycharm选择运行环境的问题
![](https://img.aspxhome.com/file/2023/4/75264_0s.jpg)
JS实现屏蔽网页右键复制及ctrl+c复制的方法【2种方法】
![](https://img.aspxhome.com/file/2023/9/136379_0s.png)
使用Python实现在Windows下安装Django
![](https://img.aspxhome.com/file/2023/9/86489_0s.png)
TensorFlow在MAC环境下的安装及环境搭建
![](https://img.aspxhome.com/file/2023/0/125130_0s.png)
最新python 字符串数组互转问题
python3.7环境下sanic-ext未生效踩坑解析
Go语言string,int,int64 ,float之间类型转换方法
使用selenium模拟登录解决滑块验证问题的实现
![](https://img.aspxhome.com/file/2023/9/99099_0s.png)
ORACLE常用数值函数、转换函数、字符串函数
mysql 循环批量插入的实例代码详解
配置 SQL Server 2005 以允许远程连接的方法
Oracle分析函数用法详解
![](https://img.aspxhome.com/file/2023/4/64834_0s.png)
用python绘制彩色螺旋线代码
![](https://img.aspxhome.com/file/2023/4/77894_0s.jpg)
JavaScript程序执行顺序问题总结
使用 XMLSPY 设计项目的 Schema 原型
![](https://img.aspxhome.com/file/UploadPic/20108/24/20100812205715286-86s.jpg)
Python脚本实现一键自动整理办公文件
![](https://img.aspxhome.com/file/2023/5/121505_0s.jpg)