问题背景
前后端分离项目中前端ajax发起请求,后端接受请求并处理,如果发起请求的前端所在域和处理请求的后端不在同一个域内,那么就会产生跨域的问题
只有当
- protocol(协议)、domain(域名)、port(端口)三者一致。
- protocol(协议)、domain(域名)、port(端口)三者一致。
- protocol(协议)、domain(域名)、port(端口)三者一致。
才是同源。
CROS简介
如果我们发送的跨域请求为“非简单请求”,浏览器会在发出此请求之前首先发送一个请求类型为OPTIONS的“预检请求”,验证请求源是否为服务端允许源,这些对于开发这来说是感觉不到的,由浏览器代理。
简单请求
“简单请求”满足以下特征:
- 请求方法是以下三种方法之一:
- HEAD
- GET
- POST
- HTTP的头信息不超出以下几种字段:
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type:
application/x-www-form-urlencoded、 multipart/form-data、text/plain
非简单请求
不满足这些特征的请求称为“非简单请求”,例如:content-type=applicaiton/json , method = PUT/DELETE...
进行非简单请求时候 , 浏览器会首先发出类型为OPTIONS的“预检请求”,请求地址相同 ,
CORS服务端对“预检请求”处理,并对Response Header添加验证字段,客户端接受到预检请求的返回值进行一次请求预判断,验证通过后,主请求发起。
解决方案
这里提供两种较为简单的解决方案
客户端通过ajax调用本地php文件发起请求
这种方案需要单独创建一个用来发送请求的php文件,ajax文件直接获取这个同域下用来发送请求的客php文件的返回值,这样就不存在跨域的问题了,但是这种方案仅适合用于个人的一些小项目
服务端添加允许跨域的代码
- 客户端添加允许跨域的信息头
// 允许所有域名进行跨域请求 header("Access-Control-Allow-Origin: *"); // 允许的请求方法 header("Access-Control-Allow-Methods: GET, POST"); // 允许的请求头部字段 header("Access-Control-Allow-Headers: Content-Type, Authorization, x-requested-with");
- 客户端单独处理OPTIONS请求
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { header("Access-Control-Allow-Origin: *"); // 允许的请求方法 header("Access-Control-Allow-Methods: GET, POST"); // 允许的请求头部字段 header("Access-Control-Allow-Headers: Content-Type, Authorization, x-requested-with"); // 返回 200 OK 状态码 // http_response_code(200); // 结束响应 exit; }