前言:
今天处理了一个之前一直没有遇到过的 CORS 的 AJAX 的跨域请求受限的问题。状况是一台放在 linux 服务器的部署在 apache 上的 php 程序使用二级域名,受到另一台 windows 服务器上的部署在 IIS 中的 WEB 网站的 AJAX 请求,遇到了的被拦截错误。
场景:
被访问的 web 环境
操作系统:linux,web软件:apache,web程序:php
跨域访问的 web 环境
操作系统:windows,web软件:iis,web程序:asp/php
被拦截时的错误提示:
Access to XMLHttpRequest at 'XXX' from origin 'XXX' has been blocked by CORS policy: Request header field x-requested-with is not allowed by Access-Control-Allow-Headers in preflight response.
在寻找解决方法时了解了一下 CORS
CORS:全称”跨域资源共享”(Cross-origin resource sharing)。
CORS需要浏览器和服务器同时支持,才可以实现跨域请求,目前几乎所有浏览器都支持CORS,IE则不能低于IE10。CORS的整个过程都由浏览器自动完成,前端无需做任何设置,跟平时发送ajax请求并无差异。so,实现CORS的关键在于服务器,只要服务器实现CORS接口,就可以实现跨域通信。
解决方案
PHP 程序部分
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers:Origin, X-Requested-With, Content-Type, Accept");
header('Access-Control-Allow-Credentials', true);
header('Access-Control-Allow-Methods: POST,GET');
JQUERY 请求部分
$.ajax({
type: 'post',
url: "",
data: {},
dataType: 'json',
crossDomain: true,
success: function (res) {
console.log(res);
},
error: function (data) {
console.log(data);
}
});
apache 配置部分
<VirtualHost *:80>
ServerAdmin webmaster@example.com
DocumentRoot "/www/wwwroot/xxx"
Header set Access-Control-Allow-Origin *
Header set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept,Authorization"
header set Access-Control-Allow-Credentials: true
ServerName 7ce0907b.xxx
ServerAlias xxx
#errorDocument 404 /404.html
……
</VirtualHost
2021-07-07 记:
也可以在伪静态(.htaccess)中直接写,这样可以解决当有SSL加持时的需求,不用80和443两个端口的 VirtualHost 中去徘徊解决(结果还是问题多多,这是博主实践后的体会)
<IfModule mod_rewrite.c>
# Options +FollowSymlinks -Multiviews
# PHP Frame Router
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?s=/$1 [QSA,PT,L]
# CORS
Header set Access-Control-Allow-Origin *
Header set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept,Authorization"
header set Access-Control-Allow-Credentials: true
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
# Header set Access-Control-Allow-Headers "X-Requested-With, Content-Type, Accept,Authorization"
</IfModule>
nginx 配置部分
2021-09-14 记:
这回环境使用的是 nginx
location / {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
if ($request_method = 'OPTIONS') {
return 204;
}
if (!-e $request_filename){
rewrite ^(.*)$ /index.php?s=$1 last; break;
}
}