HTTP系列之跨域资源共享机制(CORS)介绍

前言

本文将继续解析详解HTTP系列1中的请求/ 响应报文的首部字段,今天带来的跨域资源共享(CORS)机制,具体内容包括CORS的原理、流程、实战,希望能给大家带来收获!



CORS简介

跨域资源共享(CORS)是一种机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器不同的域、协议或端口请求一个资源时,此请求就是一个跨域 HTTP 请求

出于安全原因,浏览器限制从脚本内发起的跨源HTTP请求(或者是返回结果被浏览器拦截)。因为要确保后台传递过来数据的可靠性,就必须前后端关于CORS的设置是一致的,而解决此方法要么是后台放开跨域限制,要么是前端被动配合后台(这往往与业务不符合)。



两类CORS

根据浏览器与后台交互逻辑的不同,CORS一般可分为两类:
 

简单请求

满足条件:

  1. 请求方法是以下三种方法之一: HEAD , GET , POST
  2. HTTP的头部信息不超过一下几种字段:
    • Accept
    • Accept-Language
    • Content-Language
    • Last-Event-ID
    • Content-Type:只限于三个值application/x-www-form-urlencodedmultipart/form-datatext/plain

基本流程:

  1. 浏览器判断请求是简单请求,自动在头信息之中,添加一个Origin字段,包含了请求来自的源(协议+域名+端口);
  2. 服务器根据这个值,决定是否同意这次请求(根据已有配置)。如果是在许可范围内,则返回正确HTTP响应并附带``Access-Control-Allow-Origin的`等头部字段信息,浏览器正常运行;如果不带这类字段,则浏览器会报错;
  3. 如果跨域被禁,抛出的错误会被XMLHttpRequest对象的onerror函数捕获,下同。

 

预检请求

不是简单请求则都是预检请求。

基本流程:

  1. 非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。

  2. 浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则不会发出后续请求并报错。



实战代码

简单模式下放开跨域:
/**	
*	server.js
*/
const express = require("express");
var app = express();

app.use("/*",(req,res,next)=>{
  res.header("Access-Control-Allow-Origin","*");			// 放开访问权限给所有地址
  res.header("Access-Control-Allow-Headers","*");	// 这个也会匹配
  res.header("Access-Control-Allow-Methods","PUT, POST, GET, DELETE, OPTIONS");// 这个也会匹配
  res.header("X-Powered-By","3.2.1");
  res.header("Content-Type","text/plain; charset=utf-8");

  next();
});

app.post("/data",(req,res)=>{
  res.send("回复消息了");
});

app.listen(8081,()=>{
  console.log("listen on 8081");
});





HTTP系列之跨域资源共享机制(CORS)介绍_第1张图片
 

简单模式下禁止跨域:
/**
* server.js
*/
// 修改语句为如下,其他不变
res.header("Access-Control-Allow-Origin","http://127.0.0.1");

HTTP系列之跨域资源共享机制(CORS)介绍_第2张图片
 

预检模式下允许跨域:
/**
* server.js
*/
// 修改语句为如下,其他不变,
res.header("Access-Control-Allow-Origin","*");	// 放开访客限制

HTTP系列之跨域资源共享机制(CORS)介绍_第3张图片
HTTP系列之跨域资源共享机制(CORS)介绍_第4张图片

 

预检模式下禁止跨域:

// 添加头部字段,这样请求会变成预检请求
request.setRequestHeader("Content-Type","application/json");
/**
* server.js
*/
// 修改语句为如下,其他不变,
// 限制访客地址只是禁止跨域的一种,也可以限制访问方法、限制访问头部字段
res.header("Access-Control-Allow-Origin","http://127.0.0.1");

HTTP系列之跨域资源共享机制(CORS)介绍_第5张图片



withCredentials属性

想要发送Cookie和HTTP认证信息,必须在两方同时开启withCredentials属性。

// 服务器端
res.header("Access-Control-Allow-Credentials","true");

// 客户端
request.setRequestHeader("withCredentials","true");

此外,如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名。并且Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie也无法读取服务器域名下的Cookie。

你可能感兴趣的:(HTTP系列之跨域资源共享机制(CORS)介绍)