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获得的回应是拒绝性质的,比如404403500等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");