跨域问题服务端解决办法 Request header field Authorization is not allowed by Access-Control-Allow-Headers

tp5--修改全局跨域

 

在“项目目录/public/index.php“文件
在代码前面加上:

// 跨域
header("Access-Control-Allow-Origin:*");
header("Access-Control-Allow-Methods:GET, POST, OPTIONS, DELETE");
header("Access-Control-Allow-Headers:DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type, Accept-Language, Origin, Accept-Encoding");
header('Access-Control-Max-Age:72000');
// 否允许发送Cookie
header('Access-Control-Allow-Credentials:true');
// 响应头设置
header("Access-Control-Allow-Headers: X-Requested-With, Content-Type, Accept, Apikey");

 

tp5--修改单接口跨域

在方法里
在方法内前面加上:

// 跨域
header("Access-Control-Allow-Origin:*");
header("Access-Control-Allow-Methods:GET, POST, OPTIONS, DELETE");
header("Access-Control-Allow-Headers:DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type, Accept-Language, Origin, Accept-Encoding");
header('Access-Control-Max-Age:72000');
// 否允许发送Cookie
header('Access-Control-Allow-Credentials:true');
// 响应头设置
header("Access-Control-Allow-Headers: X-Requested-With, Content-Type, Accept, Apikey");

 

 

注意:前端请求发送两次的情况 

原因:

XMLHttpRequest会遵守同源策略(same-origin policy). 也即脚本只能访问相同协议/相同主机名/相同端口的资源, 如果要突破这个限制, 那就是所谓的跨域, 此时需要遵守CORS(Cross-Origin Resource Sharing)机制。

那么, 允许跨域, 不就是服务端设置Access-Control-Allow-Origin: *就可以了吗? 普通的请求才是这样子的, 除此之外, 还一种叫请求叫preflighted request。

preflighted request在发送真正的请求前, 会先发送一个方法为OPTIONS的预请求(preflight request), 用于试探服务端是否能接受真正的请求,如果options获得的回应是拒绝性质的,比如404\403\500等http状态,就会停止post、put等请求的发出。

那么, 什么情况下请求会变成preflighted request呢? 

1、请求方法不是GET/HEAD/POST
2、POST请求的Content-Type并非application/x-www-form-urlencoded, multipart/form-data, 或text/plain
3、请求设置了自定义的header字段
上面请求中设置了自定义的headers字段,出现了option请求。把自定义headers字段删掉后,只访问一次

如何解决

【HTTP】如何避免OPTIONS请求?
非简单请求 会在正式通信之前,增加一次HTTP请求,称之为预检请求。浏览器会先发起OPTIONS方法到服务器,以获知服务器是否允许该实际请求。
后端在请求的返回头部添加:
 
Access-Control-Max-Age:(number)  。数值代表preflight request  (预检请求)的返回结果(即 Access-Control-Allow-Methods 和Access-Control-Allow-Headers 提供的信息) 可以被缓存多久,单位是秒。
 
例如:将预检请求的结果缓存10分钟:
 
Access-Control-Max-Age: 600 
 
不同浏览器有不同的上限。在Firefox中,上限是24h(即86400秒),而在Chromium 中则是10min(即600秒)。Chromium 同时规定了一个默认值 5 秒。
如果值为 -1,则表示禁用缓存,每一次请求都需要提供预检请求,即用OPTIONS请求进行检测。
 
Access-Control-Max-Age方法对完全一样的url的缓存设置生效,多一个参数也视为不同url。也就是说,如果设置了10分钟的缓存,在10分钟内,所有请求第一次会产生options请求,第二次以及第二次以后就只发送真正的请求了。

 

 

 

跨域问题服务端解决办法

一般在入口文件加

header('Access-Control-Allow-Origin:*');
// 响应类型
header('Access-Control-Allow-Methods:*');
// 响应头设置
header('Access-Control-Allow-Headers:content-type,token,id');
header("Access-Control-Request-Headers: Origin, X-Requested-With, content-Type, Accept, Authorization");
// 否允许发送Cookie
header('Access-Control-Allow-Credentials:true');
// 响应头设置
header("Access-Control-Allow-Headers: X-Requested-With, Content-Type, Accept, Apikey");

都能解决,要是不行试试下面

if($_SERVER['REQUEST_METHOD'] == 'OPTIONS'){
    header("Access-Control-Allow-Origin: *");
    header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization");
    header('Access-Control-Allow-Methods: GET, POST, PUT,DELETE,OPTIONS,PATCH');
    file_put_contents('option.txt',json_encode($_REQUEST));
    exit;
}

header('Access-Control-Allow-Origin:*');
// 响应类型
header('Access-Control-Allow-Methods:*');
// 响应头设置
header('Access-Control-Allow-Headers:content-type,token,id');
header("Access-Control-Request-Headers: Origin, X-Requested-With, content-Type, Accept, Authorization");

// 否允许发送Cookie
header('Access-Control-Allow-Credentials:true');
// 响应头设置
header("Access-Control-Allow-Headers: X-Requested-With, Content-Type, Accept, Apikey");

 

posted @ 2021-08-28 18:53  mingruqi  阅读(4090)  评论(0编辑  收藏  举报