教程:解决网站CORS跨域 http和https混合内容问题

今天在捣鼓vercel php运行时的时候,发现了个令人头痛的问题。就是跨域资源共享(CORS)问题和HTTPS页面下的混合内容(Mixed Content)警告。

相信很多朋友都有类似的经历,当你在一个网页中嵌入别的网站资源链接时,浏览器控制台会频繁抛出Blocked by CORS Policy错误,或用户界面因HTTP资源被屏蔽而显示异常。这就是典型的跨域问题和混合内容警告!

vercel php有感兴趣的朋友可以去研究下

项目地址: https://github.com/vercel-community/php

跨域资源共享CORS问题解决:

CORS(Cross-Origin Resource Sharing)是浏览器的一种安全机制,用于限制不同源(协议、域名、端口)之间的资源请求。在开发前后端分离项目或调用第三方API接口时,常会遇到“跨域请求被阻止”的问题。

一.如果你是网站开发者,进入网站修改nginx配置

1.aapanel面板为例,进入/www/server/panel/vhost/nginx,点击需要修改的网站conf文件

2.在root /www/wwwroot/xxx下面添加一段代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 新增 CORS 配置 --------------------------------------------------
# 核心 CORS 头
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;

location / {


# 处理 OPTIONS 预检请求
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}

# 原有静态文件配置(已存在,保持不动)
expires 30d;
error_log /dev/null;
access_log off;
}
# ----------------------------------------------------------------其它代码保持

3.保存,重启一下即可

二. 使用代理服务器绕过跨域限制

Cloudflare提供了Workers(轻量级无服务器函数)功能,允许你自定义HTTP请求和响应过程。你可以通过创建一个Worker来实现代理请求并加上适当的CORS响应头,从而绕过浏览器的同源策略。Cloudflare免费账户的Worker每天有请求上限(如 10 万次/天)

三. 配置浏览器临时关闭 CORS

1.关闭所有正在运行的Chrome浏览器窗口

2.使用命令行运行以下命令(可新建 .bat 文件):

1
2
3
4
5
6

chrome.exe --disable-web-security --user-data-dir="C:/ChromeDev"
--disable-web-security:禁用浏览器的安全策略

--user-data-dir:指定一个新的用户配置文件目录(防止影响你的主配置)

3.虽然可行,但是不推荐使用

四. 通过浏览器扩展程序解决跨域问题

CORS Unblock就是一个不错的选择

http和https混合内容 Mixed Content问题解决:

https页面中,Mixed Content(混合内容)是指页面通过HTTPS加载,但其资源(如图片、脚本、样式表等)部分通过HTTP加载,这会导致安全风险

一. 将源http改为https

这是最简单又有效的方法,最推荐的方式,修改源代码中资源链接即可

二. 使用相对协议

将http: 改为 //,自动使用页面所在的协议,例如:

1
2
3
4

<!-- 协议相对 -->
<script src="//example.com/script.js"></script>

但是这种方式在现代开发中已不常用,推荐直接使用https明确指定

三. 替换资源来源

若资源提供方不支持,替换为提供https的其他CDN或源。或将资源下载到本地服务器,自己通过https提供

四. 允许浏览器设置

1.chrome依次打开设置-隐私和安全-更多内容设置-不安全内容-添加允许显示不安全内容

2.或者直接输入

1
2
3

chrome://settings/content/insecureContent

五.直接使用代理服务器中转

1.将下面代码保存为pojie.php文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

<?php
error_reporting(E_ERROR | E_PARSE);
@ini_set('max_execution_time', '0');
@ini_set("memory_limit", '-1');

// 原始 URL 参数
$raw_url = $_GET["url"] ?? '';

if (!empty($raw_url) && substr($raw_url, 0, 4) == 'http') {

// 对 URL 进行解析
$parts = parse_url($raw_url);
if (!$parts) {
http_response_code(400);
exit("Invalid URL");
}

// 编码路径部分,保留斜杠
$path = isset($parts['path']) ? implode('/', array_map('rawurlencode', explode('/', $parts['path']))) : '';
$query = isset($parts['query']) ? '?' . $parts['query'] : '';
$encoded_url = "{$parts['scheme']}://{$parts['host']}" . (isset($parts['port']) ? ":{$parts['port']}" : '') . "$path$query";

$ext = pathinfo($path, PATHINFO_EXTENSION);

// 支持的 MIME 类型
$types = array(
'gif' => 'image/gif',
'jpeg' => 'image/jpeg',
'jpg' => 'image/jpeg',
'jpe' => 'image/jpeg',
'png' => 'image/png',
'mp3' => 'audio/mpeg',
'lrc' => 'text/plain',
);
$mime = isset($types[$ext]) ? $types[$ext] : 'application/octet-stream';
header("Content-Type: $mime");

// 支持断点续传
$range = $_SERVER['HTTP_RANGE'] ?? '';

// 初始化 CURL
$ch = curl_init($encoded_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

if (!empty($range)) {
curl_setopt($ch, CURLOPT_RANGE, str_replace("bytes=", "", $range));
}

$response = curl_exec($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($response, 0, $header_size);
$body = substr($response, $header_size);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

// 设置返回状态码
http_response_code($http_code);

// 保留关键响应头
foreach (explode("\r\n", $headers) as $header) {
if (stripos($header, "Content-Range") === 0 ||
stripos($header, "Content-Length") === 0 ||
stripos($header, "Accept-Ranges") === 0 ||
stripos($header, "Content-Type") === 0) {
header($header);
}
}

echo $body;
}
?>

2.将该php文件上传到网站根目录

3.使用如下格式访问即可解决

1
2
3

https://xxx.com/pojie.php/?url=http://xxx

4.如果出现跨域问题,可以按照我上面提供的方法

结束语录:

以上方法大部分都是涉及pc浏览器。为了兼容手机浏览器访问,强烈建议使用代理服务器,或者修改nginx配置,已避免出现问题。