空痕博客 - 编程技术分享

完美解决请求跨域问题

KongHen02
一天前发布 /正在检测是否收录...

问题说明

1. 什么是跨域问题?

跨域问题是由浏览器的同源策略(Same-Origin Policy)引起的一种安全限制。当网页尝试访问不同源(协议、域名、端口任一不同)的资源时,浏览器会阻止这种请求。

2. 同源策略定义

两个URL在以下三个方面完全相同时才属于同源:

  • 协议(Protocol):http、https等
  • 域名(Domain):www.example.com
  • 端口(Port):80、443等

3. 常见的跨域场景

// 同源示例
http://example.com/app1 --> http://example.com/app2  // 同源

// 跨域示例
http://example.com --> https://example.com           // 协议不同
http://test.example.com --> http://api.example.com        // 域名不同
http://example.com:80 --> http://example.com:8080    // 端口不同

4. 浏览器端表现

// 预检请求
Access to XMLHttpRequest at 'http://api.example.com' from origin 'http://test.example.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
// 正式请求
Access to XMLHttpRequest at 'http://api.example.com' from origin 'http://test.example.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

跨域问题.png

跨域检测

跨域检测工具:跨域测试工具

解决方法

1. 服务端配置允许跨域(后端属于自己)

基于宝塔面板配置

最新版宝塔面板(11.0.0+)

最新版宝塔配置非常简单,直接在站点设置里开启允许跨域即可。

配置步骤:

  1. 打开宝塔面板“网站”,点击对应的站点
  2. 点击“其他设置” - “跨域访问CORS配置” - “状态” - 开启 - “保存” 即可

步骤演示

低版本宝塔面板(< 11.0.0)

低版本需要修改站点的配置文件,略微麻烦。

配置步骤:

  1. 打开宝塔面板“网站”,点击对应的站点
  2. 点击“配置文件”,添加以下内容即可
# 解决跨域问题--START
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS,PUT,DELETE;
add_header Access-Control-Allow-Headers DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization;
add_header Access-Control-Expose-Headers Content-Length,Content-Range;
location / {
    # 处理 OPTIONS 预检请求
    if ($request_method = 'OPTIONS') {
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods GET,POST,OPTIONS,PUT,DELETE;
        add_header Access-Control-Allow-Headers DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization;
        add_header Access-Control-Expose-Headers Content-Length,Content-Range;
        add_header Access-Control-Max-Age 1728000;
        add_header Content-Type text/plain;
        add_header Content-Length 0;
        return 204;
    }
}
# 解决跨域问题--END

步骤演示

存在的问题

需要删除自己代码里的允许跨域配置,否则会出现跨域冲突,出现错误。

// 配置冲突
Access to XMLHttpRequest at 'https://test.khkj6.com/' from origin 'https://tool.khkj.xyz' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed.

配置冲突

2. 使用代理(服务端不属于自己)

跨域是浏览器端检测请求不同源,对请求进行拦截,所以,只要不使用浏览器发送请求就可以解决。

使用自己同源的域名或配置了允许跨域的域名进行代理

以下提供最基础的php演示

$ch = curl_init();

// POST 数据
$postData = [
    'name' => '张三',
    'email' => 'zhangsan@example.com',
    'age' => 25
];

curl_setopt_array($ch, [
    CURLOPT_URL => "https://api.example.com/users",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => http_build_query($postData), // 表单格式
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/x-www-form-urlencoded',
    ]
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

curl_close($ch);

echo "状态码: " . $httpCode . "\n";
echo "响应: " . $response;

使用非浏览器发送请求

在app、小程序等环境中,不会出现跨域问题。

3. 浏览器禁用安全策略(仅开发环境)

--disable-web-security --user-data-dir=文件夹路径

配置步骤:

chrome浏览器为例

  1. 在任意位置创建一个文件夹(用于存储禁用安全策略的浏览器数据)

示例路径:C:\MyChromeDevUserData
完整代码:--disable-web-security --user-data-dir=C:\MyChromeDevUserData

  1. 复制文件夹路径
  2. 找到chrome的安装目录
  3. chrome.exe创建快捷方式
  4. 打开创建的快捷方式的属性

打开属性

  1. 在属性 - 目标后方添加代码

修改目标路径

  1. 使用新建的快捷方式进入,不会触发跨域问题
© 版权声明
THE END
喜欢就支持一下吧
点赞 0 分享 收藏
评论 抢沙发
取消
易航博客