Yii处理Cors跨域调用

文章目录
[隐藏]

1.Cors介绍

Cros 跨域资源共享(Cross-origin resource sharing),是一个W3C标准
它允许浏览器向跨源服务器发出XMLHttpRequest请求,从而绕过AJAX的同源策略(Same-orgin-Policy)
Same-orgin-Policy:在一个浏览器中访问的网站不能访问另一个网站中的数据,除非这两个网站具有相同的Orgin,也就是拥有相同的协议、主机地址以及端口。如果某项不一致,资源就被认为是不同的Orgin,访问被拒绝。

2.Cors分类

简单请求(simple Request):满足以下两个条件
    1. 请求方法为:GET|POST|HEAD
    2. HTTP 的头信息只包含在:  
        Accept  
        Accept-Language 
        Content-Language  
        Content-Type (application/x-www-form-urlencoded | multipart/form-data | text/plain )
        Last-Event-ID  
非简单请求(not-so-simple-request):其他的请求都是非简单请求

3.跨域请求处理(简单请求)

浏览器会自动添加一个Orgin请求头,Orgin包含协议名称、地址、端口

处理:
Yii:index.php 添加响应头
1. Access-Control-Allow-Origin(必须)
该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。

2. Access-Control-Allow-Credentials(可选)
它的值是一个布尔值,表示是否允许发送Cookie。
默认情况下,Cookie不包括在CORS请求之中。
设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。
这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。

3. Access-Control-Expose-Headers(可选)
CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:
Cache-Control | Content-Language | Content-Type | Expires | Last-Modified | Pragma
如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定,并以逗号进行分隔。

4.跨域请求处理(非简单请求)

预检请求:
非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。
非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。
只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错

预检请求以OPTIONS方式请求,请求头包含
1. Origin: 表示请求来自哪个源。
2. Access-Control-Request-Method – 该项内容是实际请求的种类,可以是GET、POST之类的简单请求,也可以是PUT、DELETE等等。
3. Access-Control-Request-Headers – 该项是一个以逗号分隔的列表,当中是复杂请求所使用的头部

处理:
Yii:index.php 添加响应头
    1. Access-Control-Allow-Origin(必含)
    和简单请求一样的,必须包含一个域。
    
    2. Access-Control-Allow-Methods(必含)
    这是对预请求当中Access-Control-Request-Method的回复,这一回复将是一个以逗号分隔的列表。尽管客户端或许只请求某一方法,但服务端仍然可以返回所有允许的方法,以便客户端将其缓存。
    
    3. Access-Control-Allow-Headers(当预请求中包含Access-Control-Request-Headers时必须包含)
    这是对预请求当中Access-Control-Request-Headers的回复,和上面一样是以逗号分隔的列表,可以返回所有支持的头部。
    
    4. Access-Control-Allow-Credentials(可选)
    和简单请求当中作用相同。
    
    5. Access-Control-Max-Age(可选)
    以秒为单位的缓存时间。预请求的的发送并非免费午餐,允许时应当尽可能缓存。

或者可以检测OPTIONS请求直接退出请求
if($_SERVER['REQUEST_METHOD'] == 'OPTIONS'){
    exit;
}

5.实例(index.php)添加响应头

<?php
// comment out the following two lines when deployed to production
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');


header('Access-Control-Allow-Origin:*');
header('Access-Control-Allow-Headers:Content-Type');
header('Access-Control-Allow-Methods:GET, POST, OPTIONS, PUT, DELETE, PATCH');
if($_SERVER['REQUEST_METHOD'] == 'OPTIONS'){
    exit;
}

require __DIR__ . '/../vendor/autoload.php';
require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';

$config = require __DIR__ . '/../config/web.php';

(new yii\web\Application($config))->run();
211 人浏览过

发表评论

邮箱地址不会被公开。 必填项已用*标注