关于跨域的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于跨域的问题相关的知识,希望对你有一定的参考价值。

参考技术A 一、在前端开发过程中,如果准备开发富应用,跨域的问题将会随之而来。

        我们先看看什么是跨域呢:

         所谓跨域,或者异源,是指主机名(域名)、协议、端口号只要有其一不同,就为不同的域(或源) 。出于保护用户数据的目的,浏览器有一个最基本的策略就是同源策略,只允许页面内的脚本访问当前域的资源(加载脚本、资源等不受此限制)。

二、如果浏览器厂商不对跨域请求进行处理,会给我们带来什么危害呢?

        有心人士(病毒制造者)会利用这个漏洞进行如下攻击:

        1. CSRF/XSRF 攻击 ,简单的来讲就是在 b.com 页面中请求 a.com 的接口(浏览器会自动带上 用户在 a.com 的 cookie),从而获取用户的在 a.com 的相关信息。

        2. XSS 注入攻击 ,类似于 SQL 攻击,提交含有恶意脚本的数据到服务器,从而达到破坏页面或者获取用户的 cookie。

三、我们了解到了什么是跨域,那我们又应该如何解决呢,现在找到了这些比较权威的文章,大家先品读一下:

        1. mozilla 官方网站关于跨域的文章(Cross Origin), HTTP访问控制(CORS)

        2. mozilla 官方网站关于浏览器同源策略的简要介绍(Same Origin),  浏览器的同源策略

四、读完这些文章,你打算怎么处理跨域问题呢,我先谈谈自己关于跨域的解决方案:

        1. 采用 CORS 协议,直接在 nginx 中设置允许跨域的 header(也可以在后端的应用程序内设置,不过在 Nginx 入口配置的话更加统一),在 location 配置中直接使用指令 add_header( 官方文档链接 ),示例配置如下:

        2. 使用 JSONP,也是需要后端配合,利用“浏览器加载脚本、资源时不受同源策略的约束”这个特性,但是这种方式非常受限制,例如只能使用 GET 请求,不能携带自定义 header 等。

        3. 其他的一些方法,例如 window.name, document.domain 以及 html5 中的特性 window.postMessage 等

五、其他参考链接

        1.  浅谈JS跨域问题

        2. 跨域资源共享 CORS 详解----阮一峰

六、声明

        现在网络上的知识非常复杂,有些是摘自权威书籍的,有些是作者自己理解然后记录下来的,有些是瞎掰的,所以一定要结合情况多多甄别,对于有权威文档的知识点,建议先参考文档。

关于跨域的cookie问题

cors下的cookie问题可以参考阮一峰的博客链接:http://www.ruanyifeng.com/blog/2016/04/cors.html

但是在实际开发当中还是会遇到点小问题,这里记录一下:

在火狐浏览器当中,如果xhr.async: false,那么在火狐浏览器下会报错。

默认的情况下,cors做到跨域之后是没有供应凭证(cookie、HTTP认证及客户端SSL证实等)(童鞋们都有牵扯到cookie吧,如果大神的网站一丁点都不占cookie的,此文略过)。重点来了,我们可以使用ajax配置项 withCredentials来解决这个问题,下来分别看看原生xhr和jquery的ajax是怎么做配置的:  

复制代码
//原生的配置
var xhr = new XMLHttpRequest();
xhr.open(\'GET\', \'http://www.xxx.com/api\');
xhr.withCredentials = true;
xhr.async=false; xhr.onload = onLoadHandler; xhr.send();
复制代码
复制代码
//jquery ajax配置
$.ajax({
            type: "GET",
            url: \'data/tree.json\',
async:false, xhrFields: { withCredentials: true } }).done(function(data) { console.log(data); });
复制代码

但是!!!!在火狐浏览器中你会发现报错了

 

也就是说在启用同步模式的ajax后,在火狐浏览器中withCredentials配置是并不起作用的,并且不能正常返回数据,导致我们的请求“失败!”

解决方案:

jquery配置模式需要修改:

复制代码
$.ajax({
            type: "GET",
            dataType: "json",
            url: \'data/tree.json\',
            beforeSend: function(xhr) {
                xhr.withCredentials = true;
            }
        }).done(function(data){
         console.log(data);
});
复制代码

将withCredentials配置写进beforeSend函数,就可以解决了

以上是关于关于跨域的问题的主要内容,如果未能解决你的问题,请参考以下文章

flask关于跨域的问题

h5标签canvas关于getImageData跨域的问题

单点登录 关于Cookie跨域的问题

关于跨域的cookie问题

关于跨域的几种方法

关于ajax跨域的一些解决方案