什么是跨域?(CORS、同源策略)

同源策略:限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的关键的安全机制。(来自 MDN 官方的解释)

受浏览器同源策略的限制,非同源的两个 URL 间不能通信,非同源的脚本不能操作其他源下面的对象,但在实际开发场景中, 这种情况经常出现, 此时需要通过跨域进行非同源通信

跨域问题的来源是浏览器为了请求安全而引入的基于同源策略的安全特性。当页面和请求的协议、主机名或端口不同时,浏览器判定两者不同源,即为跨域请求。需要注意的是跨域是浏览器的限制,服务端并不受此影响。

出于安全性,浏览器限制脚本内发起的跨源 HTTP 请求。例如,XMLHttpRequest 和 Fetch API 遵循同源策略。这意味着使用这些 API 的 Web 应用程序只能从加载应用程序的同一个域请求 HTTP 资源,除非响应报文包含了正确 CORS 响应头。

当产生跨域时,我们可以通过 JSONP、CORS、postMessage 等方式解决。

同源策略有什么限制

  • 源包括三个部分:协议、域名、端口(http 协议的默认端口是 80)。如果有任何一个部分不同,则源不同,那就是跨域了。
  • 限制:这个源的文档没有权利去操作另一个源的文档。这个限制体现在:(要记住)
    • Cookie、LocalStorage 和 IndexDB 无法获取。
    • 无法获取和操作 DOM。
    • 不能发送 Ajax 请求。我们要注意,Ajax 只适合同源的通信。

但是有三个标签是允许跨域加载资源:

  • <img src=XXX>
  • <link href=XXX>
  • <script src=XXX>

特别说明两点:

第一:如果是协议和端口造成的跨域问题“前台”是无能为力的。

第二:在跨域问题上,仅仅是通过“URL 的首部”来识别而不会根据域名对应的 IP 地址是否相同来判断。“URL 的首部”可以理解为“协议, 域名和端口必须匹配”。

这里你或许有个疑问:请求跨域了,那么请求到底发出去没有?

跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了。你可能会疑问明明通过表单的方式可以发起跨域请求,为什么 Ajax 就不会?因为归根结底,跨域是为了阻止用户读取到另一个域名下的内容,Ajax 可以获取响应,浏览器认为这不安全,所以拦截了响应。但是表单并不会获取新的内容,所以可以发起跨域请求。同时也说明了跨域并不能完全阻止 CSRF,因为请求毕竟是发出去了。

常见通信方式

  • ajax:不支持跨域。
  • WebSocket:不受同源策略的限制,支持跨域
  • 跨域资源共享(CORS):不受同源策略的限制,支持跨域。一种新的通信协议标准。可以理解成是:同时支持同源和跨域的 Ajax。

常见的跨域方式

1.jsonp

利用