HTTP

跨域与 CORS

同源策略

前端开发中常见的跨域处理方式有服务端配置 CORS,以及开发环境使用代理。

同源策略限制网页脚本读取其他源的响应。是否同源由协议、主机名和端口共同决定。

  • 协议不同,例如 HTTP 与 HTTPS
  • 主机名不同
  • 端口不同

CORS

全称为跨源资源共享(Cross-Origin Resource Sharing)。服务端通过响应头声明哪些来源可以读取响应。

简单请求

什么是简单请求

  • 请求方法为 GET、HEAD 或 POST
  • 手动设置的请求头仅使用 CORS 安全列表中的字段,例如 Accept、Accept-Language、Content-Language
  • 如果设置了 Content-Type,其值仅为 application/x-www-form-urlencoded、multipart/form-data 或 text/plain

处理方式

  • 服务端根据请求的 Origin 返回相应的 Access-Control-Allow-Origin;浏览器再决定是否允许脚本读取响应。
  • 跨源请求需要携带 Cookie 时,客户端须启用凭据模式,服务端须返回 Access-Control-Allow-Credentials: true 和明确的 Access-Control-Allow-Origin(不能是 *)。

复杂请求

什么是复杂请求

不满足简单请求的都是复杂请求。

处理方式

浏览器会先发送 OPTIONS 预检请求。服务端允许相应的方法和请求头后,浏览器才会发送正式请求。

Proxy

如果你的前端应用和后端 API 服务器没有运行在同一个主机上,你需要在开发环境下将 API 请求代理到 API 服务器。

这个问题可以通过 vue.config.js 中的 devServer.proxy 选项来配置。

devServer.proxy 可以是一个指向开发环境 API 服务器的字符串:

module.exports = {
  devServer: {
    proxy: "http://localhost:4000"
  }
};

这会告诉开发服务器将未匹配到静态文件的请求代理到 http://localhost:4000。

如果你想要更多的代理控制行为,也可以使用一个 path: options 成对的对象。完整的选项可以查阅 http-proxy-middleware 。

module.exports = {
  devServer: {
    proxy: {
      // 请求的url中,遇到 /api 开头的请求,则代理到 <url>
      "/api": {
        target: "<url>",
        ws: true,
        changeOrigin: true
      },
      "/foo": {
        target: "<other_url>"
      }
    }
  }
};