教程:解决网站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下面添加一段代码


    # 新增 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 文件):


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: 改为 //,自动使用页面所在的协议,例如:


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

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

三. 替换资源来源

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

四. 允许浏览器设置

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

2.或者直接输入


chrome://settings/content/insecureContent

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

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


<?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.使用如下格式访问即可解决


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

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

结束语录:

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