A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 李盼盼老师 于 2018-4-19 16:49 编辑


【什么是跨域】
         只要协议、域名、端口有任何一个不同,都被当作是不同的域,他们之间的请求就是跨域操作。
         浏览器的同源策略会导致跨域,这里同源策略又分为以下两种
1.     DOM同源策略:禁止对不同源页面DOM进行操作。这里主要场景是iframe跨域的情况,不同域名的iframe是限制互相访问的。
2.     XmlHttpRequest同源策略:禁止使用XHR对象向不同源的服务器地址发起HTTP请求。
同源策略限制以下几种行为:
1.) Cookie、LocalStorage和 IndexDB 无法读取
2.) DOM 和 Js对象无法获得
3.) AJAX 请求不能发送

【常见的跨域解决方案
  • 通过jsonp跨域
  • document.domain + iframe跨域
  • postMessage跨域跨域资源共享(CORS


通过jsonp跨域
     通常为了减轻web服务器的负载,我们把js、css,img等静态资源分离到另一台独立域名的服务器上,在html页面中再通过相应的标签从不同域名下加载静态资源,而被浏览器允许,基于此原理,我们可以通过动态创建script,再请求一个带参网址实现跨域通信。
1.)原生实现:
[JavaScript] 纯文本查看 复制代码
var script = document.createElement('script');

 script.type = 'text/javascript';

// 传参并指定回调执行函数为onBack

script.src = 'http://www.domain2.com:8080/login?user=admin&callback=onBack'; document.head.appendChild(script);

// 回调执行函数

function onBack(res) { alert(JSON.stringify(res)); }

服务端返回如下(返回时即执行全局函数)

onBack({"status": true, "user": "admin"})
      2.jqueryajax
     
[JavaScript] 纯文本查看 复制代码
  $.ajax({[/align]
                url: 'http://www.domain2.com:8080/login',

                type: 'get',

                dataType: 'jsonp', // 请求方式为jsonp

                jsonpCallback: "onBack", // 自定义回调函数名

               data: {}

    });

jsonp缺点:只能实现get一种请求

3.vue.js
[JavaScript] 纯文本查看 复制代码
this.$http.jsonp('http://www.domain2.com:8080/login', {

    params: {},

    jsonp: 'onBack'

}).then((res) => {

    console.log(res);

})

document.domain+ iframe跨域】
此方案仅限主域相同,子域不同的跨域应用场景
实现原理:两个页面都通过js强制设置document.domain为基础主域,就实现了同域。
1.)父窗口:(http://www.domain.com/a.html))
[JavaScript] 纯文本查看 复制代码
<iframe id="iframe" src="http://child.domain.com/b.html"></iframe>

<script>

         document.domain = 'domain.com';

    var user = 'admin';

</script>

[JavaScript] 纯文本查看 复制代码
document.domain = 'domain.com';

    // 获取父窗口中变量

alert('get js data from parent ---> ' + window.parent.user);

【跨域资源共享(CORS)】
普通跨域请求:只服务端设置Access-Control-Allow-Origin即可,前端无须设置,若要带cookie请求:前后端都需要设置。
         需注意的是:由于同源策略的限制,所读取的cookie为跨域请求接口所在域的cookie,而非当前页。如果想实现当前页cookie的写入,可参考下文:七、nginx反向代理中设置proxy_cookie_domain 和八、NodeJs中间件代理中cookieDomainRewrite参数的设置。
目前,所有浏览器都支持该功能(IE8+:IE8/9需要使用XDomainRequest对象来支持CORS)),CORS也已经成为主流的跨域解决方案。
1、 前端设置:
1.)原生ajax
[JavaScript] 纯文本查看 复制代码
// 前端设置是否带cookie

xhr.withCredentials = true;

示例代码:

var xhr = new XMLHttpRequest();// IE8/9需用window.XDomainRequest兼容

    // 前端设置是否带cookie

    xhr.withCredentials = true;

    xhr.open('post', 'http://www.domain2.com:8080/login', true);

    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

    xhr.send('user=admin');

    xhr.onreadystatechange = function() {

        if (xhr.readyState == 4 && xhr.status == 200) {

            alert(xhr.responseText);

        }

};

2.)jQuery ajax
[JavaScript] 纯文本查看 复制代码
$.ajax({

        ...

        xhrFields: {

                    withCredentials: true // 前端设置是否带cookie

        },

       crossDomain: true, // 会让请求头中包含跨域的额外信息,但不会含cookie

        ...

    });
3.)vue框架
在vue-resource封装的ajax组件中加入以下代码:
[JavaScript] 纯文本查看 复制代码
Vue.http.options.credentials = true
2、 服务端设置:
若后端设置成功,前端浏览器控制台则不会出现跨域报错信息,反之,说明没设成功。

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马