跨域HTTP请求
上一篇中提到过的同源策略,作为其一部分,XMLHttpRequest 对象通常只是用于发起和文档具有相同服务器的HTTP请求。这个限制关闭了安全漏洞,但在另一方面却阻止了大量合适使用的跨域请求。
例如,在 <form>
和 <iframe>
元素中使用跨域 URL,浏览器会显示最终的跨域文档,与此同时,浏览器却不允许我们使用原始脚本查找跨域文档的内容,根源在于同源策略。如何做到既保证浏览器的安全,又要完成跨域呢?
-
JSONP
<script>
元素并未真正受限于同源策略:它加载并执行任何来源的脚本,只须设置<script>
元素的src
属性,一旦这个元素插入到文档中,浏览器就会发送一个HTTP请求以下载src
属性所指向的 URL。之后,包含JSON编码数据的响应体会自动解码(即,执行)
响应的JSON解码数据,形如[1, 2, {"buckle": "my shoe"}]
将其包裹在一个函数名内,handleResponse([1, 2, {"buckle": "my shoe"}])
若此时有一个名为handleResponse
的函数,则相当于将响应的编码数据作为参数,执行函数,为做到这点,需要前后端约定函数名,以上便是JSONP的关键 -
CORS
CORS 全名为Cross-Origin Resource Sharing
,跨域资源共享,这种请求与传统的 Ajax 请求没有区别,浏览器一旦发现Ajax请求跨域,就会自动在请求的头部添加一些信息,若服务器实现了CORS接口,浏览器就能接收到返回的消息,实现跨域通信- 请求的方法
- HEAD
- GET
- POST
- HTTP的头信息不超过以下几种字段
- Accept
- Accept-Language
- Content-Language
- Ladt-Event-ID
- Content-type:只限于三个值 application/x-www-form-urlencoded、multipart/form-date、text/plain
详见
- 请求的方法
-
postMessage
window.postMessage() 方法被调用时,会在所有页面脚本执行完毕之后(e.g., 在该方法之后设置的事件、之前设置的timeout 事件,etc.)向目标窗口派发一个 MessageEvent 消息。 该MessageEvent
消息有四个属性需要注意: message 属性表示该message 的类型; data 属性为 window.postMessage 的第一个参数;origin 属性表示调用window.postMessage()方法时调用页面的当前状态; source 属性记录调用 window.postMessage()方法的窗口信息
详见
小结:不同的场景下,解决跨域会有不同的方案,研究跨域也不应该仅仅只是为了应付面试,背后的原理才是关键,jsonp用了script的不受限及脚本的立即执行,cors涉及到HTTP请求头,postmessage用到了window.postMessage()这个方法