跨域请求及其解决方案

 

 

目录

一、理论概述

1. 什么是跨域请求(Cross-domain Request)

2. 浏览器的同源策略(Same-origin Policy)

3. 存在的安全风险

4. CSRF攻击简介

二、跨域方案

1. 跨域资源共享(CORS)

(1)CORS简单请求

(2)CORS非简单请求(也称预检请求)

预检请求与重定向        

附带身份凭证的请求

附带身份凭证的请求与通配符

HTTP 响应首部字段

HTTP 请求首部字段 

2. JSONP请求

3. JSONP和CORS请求比较

4.子域跨父域

5. iframe跨父窗口

6. window.postMessage

7. 使用代理避开跨域请求


一、理论概述

1. 什么是跨域请求(Cross-domain Request)

​        在 HTML 中,

        大家可能注意到,JQuery是怎么实现返回数据的?其实,在JQuery的JSONP实现中,首先将你在success中定义的函数封装成jsonpCallback定义的函数,然后再封装一个脚本请求如

3. JSONP和CORS请求比较

        JSONP请求,缺点是仅支持GET请求,必须完全信任提供服务的第三方,优点是支持老式浏览器,兼容性较好。

        CORS比JSONP更强大,支持所有类型的HTTP请求。

4.子域跨父域

        子域跨父域是支持的,但是需要显式将子域的域名改成父域的,例如mail.mysite.com要请求mysite.com的数据,那么在mail.mysite.com脚本里需要执行:

document.domain = "mysite.com";

5. iframe跨父窗口

        如果iframe与父窗口也有同源策略的限制,父域无法直接读取不同源的iframe的DOM内容以及监听事件,但是iframe可以调用父窗口提供的api。iframe通过window.parent得到父窗口的window对象,然后父窗口定义一个全局对象供iframe调用。

        例如在页面通过iframe的方式嵌入一个youtobe的视频,如果需要手动播放视频、监听iframe的播放事件,页面需要引入youtobe的视频播放控制api,在这个js文件里面定义了一个全局对象YT:

if (!window['YT']) {var YT = {loading: 0,loaded: 0};}

而在视频iframe的脚本里通过window.parent获取得到父窗口即自己网站的页面:

sr = new Cq(window.parent, d, b)

自已网站的页面也是在这个YT对象自定义一些东西,如添加播放事件监听:

new YT.Player('video', { events:{ 'onStateChange': function(data){... } } });

6. window.postMessage

在上面第(5)点,父窗口无法向不同源的iframe传递东西,通过window.postMessage可以做到,父窗口向iframe传递一个消息,而iframe监听消息事件。

例如在8000端口的页面嵌入了一个9000端口的iframe:

然后9000端口post一个message:

 window.onload = function(){

window.frames[0].postMessage("hello, this is from http://localhost:8000/", "http://server.com:9000/");

}

postMessage执行的上下文必须是接收信息的window,传递两个参数,第一个是数据,第二个是目标窗口。

同时,iframe即9000端口的页面监听message事件:

 window.addEventListener("message", receiveMessage);


function receiveMessage(event){

var origin = event.origin || event.originalEvent.origin;

//身份验证

if (origin !== "http://localhost:8000"){

return;

}

console.log("receiveMessage: " + event.data);

}

这样子iframe就可收到父窗口的信息了:

同理iframe也可以向父窗口发送消息:

window.parent.postMessage("hello, this is from http://server.com:9000", "http://localhost:8000");

父窗口收到:

window.postMessage也适用于通过window.open打开的子窗口,方法类似。

补充一点,如果iframe与父窗口是同源的,则父窗口可以直接获取到iframe的内容,这个方法常用于无刷新上传文件。

7. 使用代理避开跨域请求

例如www.a.com/index.html页面去调用www.b.com/service.jsp,可以通过写一个接口www.a.com/service.jsp,由这个接口在后端去调用www.b.com/service.jsp并取到返回值,然后再返回给index.html。

 


参考链接:

1. 什么是跨域请求以及实现跨域的方案

2. Access-Control-Allow- 设置 跨域资源共享 CORS 详解

3. HTTP访问控制(CORS)

4. 同源策略和跨域请求研究

5. Jsonp解决跨域的原理及过程

 

你可能感兴趣的:(javaweb,跨域请求,同源策略,java)