初识CORS(AJAX跨源请求解决方案)

498 阅读3分钟

这是我参与更文挑战的第5天,活动详情查看: 更文挑战

什么情况下需要使用CORS?

在更新当前网页的部分区域,而不是刷新整个页面时,使用的技术为AJAX,但AJAX只能向同源网址(协议、域名、端口都相同)发出 HTTP 请求。因而前后端分离时,使用非同源网址,需要借助CORS解决跨源通讯问题。

  • AJAX (Asynchronous JavaScript and XML) :通过 JavaScript 的异步通信,发出 XMLHttpRequest 请求,从服务器获取数据后实现网页局部更新。
  • XMLHttpRequest 对象用于在后台与服务器交换数据。
  • AJAX 原本使用的HTTP(协议)+XML(内容格式),但实际 AJAX 已被泛化,可使用多种协议(file、ftp)+ 任何内容格式(字符串、二进制等)。

什么是CORS?

CORS(Cross-Origin Resource Sharing 跨域资源共享),允许浏览器向跨域的服务器,发出XMLHttpRequest 请求,从而克服了AJAX只能同源使用的限制,属于跨源 AJAX 请求的根本解决方法。

CORS特点

  1. 需要浏览器和服务器同时支持
  2. 浏览器自动完成:使用普通的AJAX通讯代码,浏览器将自动完成通讯过程。浏览器发现AJAX跨源请求后,会在在请求头中加入特殊头或发送特殊请求,因为CORS通讯实现的关键为服务器
  3. 服务器需要支持:响应头中需要有特殊头

CORS分类

  • 简单请求(simple request):满足以下两个条件的请求
    • 请求方法是以下三种方法之一:
      • HEAD
      • GET
      • POST
    • HTTP 的头信息不超出以下几种字段:
      • Accept
      • Accept-Language
      • Content-Language
      • Last-Event-ID
      • Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
  • 非简单请求(not-so-simple request):简单请求以外的请求

简单请求流程

对于简单请求,浏览器直接发出 CORS 请求:

  • 浏览器发现这次跨域 AJAX 请求是简单请求,就自动在头信息之中,添加一个Origin字段。
  • Origin字段用来说明,本次请求来自哪个域(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这次请求。
  • 如果Origin指定的源,不在许可范围内,服务器会返回一个正常的 HTTP 回应(CORS通讯的响应会包含特定字段)。

非简单请求流程

非简单请求会先查询能否通讯再正式通讯:

  • “预检”请求(preflight):在正式通信之前,增加一次 HTTP 查询请求,称为“预检”请求(preflight)。浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些 HTTP 动词和头信息字段。
  • 正式请求:预检得到肯定答复后,再正式发出XMLHttpRequest请求。

为什么会区分“简单请求”与“非简单请求”?

特殊操作(新增、删除等)对传统的没有 CORS 支持的服务器形成压力,给服务器一个提前拒绝的机会,这样可以防止服务器大量收到DELETE和PUT请求,这些传统的表单不可能跨域发出的请求。