跨域(非同源策略请求)
为什么会出现跨域
由于浏览器的同源策略限制,同源策略是一种约定,他是浏览器最核心也是最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)
什么是跨域
当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域
当前页面url | 被请求页面url | 是否跨域 | 原因 |
---|---|---|---|
http://www.test.com/ | http://www.test.com/index.html | 否 | 同源(协议、域名、端口号相同) |
http://www.test.com/ | https://www.test.com/index.html | 跨域 | 协议不同(http/https) |
http://www.test.com/ | http://www.baidu.com/ | 跨域 | 主域名不同(test/baidu) |
http://www.test.com/ | http://blog.test.com/ | 跨域 | 子域名不同(www/blog) |
http://www.test.com:8080/ | http://www.test.com:7001/ | 跨域 | 端口号不同(8080/7001) |
非同源限制
- 无法读取非同源网页的Cookie,LocalStorage ,IndexedDB
- 无法接触非同源网页的DOM
- 无法向非同源地址发送AJAX请求
解决方法
xampp
-
xampp:在本地开发时候模拟同源
但其实还是同源
jsonp
-
jsonp
script
img
link
iframe
以上四个标签不存在跨域的限制,严格来说,这个不叫跨域,跨域是指脚本代码向非同源域发送HTTP请求,这只是跨站资源请求
jsonp就是利用script标签来完成跨域的
<script src="http://localhost:8546/Service.ashx?callback=handler"></script> <script> function handler(data) { console.log(data); } </script>
public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; // 前端指定的回调函数名称 var callbackFuncName = context.Request.QueryString["callback"]; var responseData = "Hello World"; // 回调脚本,形如:handler('responseData'); var scriptContent = string.Format("{0}('{1}');", callbackFuncName, responseData); context.Response.Write(scriptContent); }
注意:1.callback函数必须是一个全局函数,2.服务端必须支持接收客户端callback函数>
-
JSONP虽然看起来很像一般的ajax请求,但其原理不同,JSONP是对文章第一小节原理的封装,是通过
jquery中的jsonp
$.ajax({
type: "get",
url: "http://localhost:8546/Service.ashx",
dataType: "jsonp",//一定要指明为jsonp
success: function (data) {
alert(data);
},
error: function () {
alert('fail');
}
});
只需要将dataType设置为"jsonp"就可以进行跨域请求了,一切就像发送非跨域请求那样简单。
jQuery为我们封装好了回调函数,一般情况下不需要我们单独去写,如果你不想在success中处理,想单独写处理函数,那么可以通过设置这2个参数来实现:
- jsonp: “callback”,//传递给服务端的回调函数参数名,如果不设置此项,则默认是"callback"
- jsonpCallback: “handler”,//传递给服务端的回调函数名称,如果不设置此项,则默认是形如"jQuery111007837897759742043_1460657212499"的由jQuery自动生成的函数名称,会自动在$.ajax方法的success中完成调用。
CORS跨域资源共享
(Cross-Origin Resource Sharing (CORS))。
同样需要服务器的支持
**跨源资源共享(CORS)**是通过客户端+服务端协作声明的方式来确保请求安全的。服务端会在HTTP请求头中增加一系列HTTP请求参数(例如Access-Control-Allow-Origin等),来限制哪些域的请求和哪些请求类型可以接受,而客户端在发起请求时必须声明自己的源(Orgin),否则服务器将不予处理,如果客户端不作声明,请求甚至会被浏览器直接拦截都到不了服务端。服务端收到HTTP请求后会进行域的比较,只有同域的请求才会处理。
局限性:要么只允许一个域,要么允许所有域
HTTP proxy
使用代理
ngnix反向代理
不需要前端做什么
postMessage
页面资源共享
webSocket
document.domain+iframe
用域同一个主域,不同子域之间
window.name+iframe
location.hash+iframe
ge
页面资源共享
webSocket
document.domain+iframe
用域同一个主域,不同子域之间
window.name+iframe
location.hash+iframe
location.hash+iframe