资讯专栏INFORMATION COLUMN

JS 跨域原因及其解决方案

voidking / 1752人阅读

摘要:产生跨域问题的原因跨域问题是浏览器同源策略限制,当前域名的只能读取同域下的窗口属性。比如,其中是协议名,是子域名,是主域名,端口号是,当在在页面中从一个请求数据时,如果这个的协议名子域名主域名端口号任意一个有一个不同,就会产生跨域问题。

产生跨域问题的原因

跨域问题是浏览器同源策略限制,当前域名的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标签是不受同源策略限制(你可以在你的网页中设置scriptsrc属性问cdn服务器中静态文件的路径)。那么就可以使用script标签从服务器获取数据,请求时添加一个参数为callbakc=?,?号时你要执行的回调方法。

前端实现

以jQuery2.1.3的ajax方法为例

javascript$.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返回的数据的格式示例

javascript/**/ typeof jQuery21307270454438403249_1428044213638 === "function" && jQuery21307270454438403249_1428044213638({"code":1,"msg":"success","data":{"test":"test"}});

这是express4.12.3关于jsonp的实现代码

javascript  // 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。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85617.html

相关文章

  • ajax跨域,这应该是最全的解决方案

    摘要:关于,强烈推荐阅读跨域资源共享详解阮一峰另外,这里也整理了一个实现原理图简化版如何判断是否是简单请求浏览器将请求分成两类简单请求和非简单请求。 前言 从刚接触前端开发起,跨域这个词就一直以很高的频率在身边重复出现,一直到现在,已经调试过N个跨域相关的问题了,16年时也整理过一篇相关文章,但是感觉还是差了点什么,于是现在重新梳理了一下。 个人见识有限,如有差错,请多多见谅,欢迎提出iss...

    ytwman 评论0 收藏0
  • Jsonp及其实现原理

    摘要:同源策略,它是由提出的一个著名的安全策略,现在所有支持的浏览器都会使用这个策略。客户端在对文件调用成功之后,也就获得了自己所需的数据,剩下的就是按照自己需求进行处理和展现了,这种获取远程数据的方式看起来非常像,但其实并不一样。 参考资料 一、先说说JSON 首先JSON是一种基于文本的数据交换方式,或者叫做数据描述格式。 JSON的优点: 基于纯文本,跨平台传递极其简单; Javas...

    TesterHome 评论0 收藏0
  • JavaScript 的同源策略及其"CORS"跨域方案

    摘要:设置的值,为其当前域或其当前域的父域。场景文档中的一个脚本执行以下语句即可通过同源检测跨源网络访问同源策略控制了不同源之间的交互。服务器确认允许之后,才发起实际的请求。 文章大纲 同源策略 同源是什么? 如何跨源,以及场景应用 源的更改 跨源网络访问 跨源脚本API访问 跨源数据存储访问 了解CORS CORS是什么? CORS功能概述 CORS关于Cookie ...

    maochunguang 评论0 收藏0
  • fetch使用的常见问题及其解决办法

    首先声明一下,本文不是要讲解fetch的具体用法,不清楚的可以参考MDN fetch教程。 引言 说道fetch就不得不提XMLHttpRequest了,XHR在发送web请求时需要开发者配置相关请求信息和成功后的回调,尽管开发者只关心请求成功后的业务处理,但是也要配置其他繁琐内容,导致配置和调用比较混乱,也不符合关注分离的原则;fetch的出现正是为了解决XHR存在的这些问题。例如下面代码: f...

    pubdreamcc 评论0 收藏0
  • 跨域知识梳理

    摘要:摘自阮一峰博客延伸阅读不涉及跨域跨源资源分享为标准兼容性参考优点提供安全的跨域数据传输,且不限于请求。跨域资源共享阿里云技术文档跨域资源共享详解阮一峰 参考:维基百科 - Root domainhttps://en.wikipedia.org/wiki...浏览器同源政策及其规避方法 - 阮一峰http://www.ruanyifeng.com/blo...window.name 跨域...

    SwordFly 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<