PHP爬虫遇CORS字体跨域错误:配置响应头与.htaccess均无效求助
解决爬虫后渲染页面的字体CORS问题
首先得帮你理清一个关键误区:你遇到的CORS错误不是爬虫本身的问题!file_get_contents是服务器端发起的请求,浏览器的CORS安全策略根本管不到它。这个错误应该是你把爬取到的HTML内容放到自己的网页里展示时,浏览器去加载目标网站(jakartagrosir.com)的字体资源时触发的——因为目标网站的服务器没有给字体资源添加Access-Control-Allow-Origin响应头,浏览器就会阻止跨域加载。
你之前在自己的脚本或.htaccess里加Access-Control-Allow-Origin没用,是因为这个响应头需要目标网站的服务器返回,你控制不了对方的服务器配置,所以自己加的规则对目标网站的资源完全无效。
下面给你几个可行的解决方案:
方案1:替换字体资源为本地/可跨域资源
爬取到HTML后,把页面里指向目标网站的字体URL全部替换成你自己服务器托管的字体,或者使用支持跨域的公共CDN字体(比如Google Fonts)。
举个简单的字符串替换示例:
$link = 'http://jakartagrosir.com/products/search-0.html?keyp=sny+230&do='; $html = file_get_contents($link); // 替换目标网站的字体CSS链接 $html = str_replace('http://jakartagrosir.com/fonts/', '/your-local-fonts/', $html); // 或者替换内联CSS里的字体URL $html = preg_replace('/url\(http:\/\/jakartagrosir\.com\/fonts\/(.*?)\)/', 'url(/your-local-fonts/$1)', $html);
方案2:做字体资源代理
写一个简单的PHP代理脚本,用来转发对目标网站字体的请求,同时在代理的响应头里添加Access-Control-Allow-Origin。
第一步:创建代理脚本(比如font-proxy.php)
<?php // 验证请求的URL合法性,避免恶意请求 $fontUrl = $_GET['url'] ?? ''; if (!filter_var($fontUrl, FILTER_VALIDATE_URL) || strpos($fontUrl, 'jakartagrosir.com/fonts/') === false) { header("HTTP/1.1 403 Forbidden"); exit; } // 获取字体内容 $fontContent = file_get_contents($fontUrl); if (!$fontContent) { header("HTTP/1.1 404 Not Found"); exit; } // 识别字体MIME类型(也可以根据文件后缀判断) $ext = pathinfo(parse_url($fontUrl, PHP_URL_PATH), PATHINFO_EXTENSION); $mimeMap = [ 'ttf' => 'font/ttf', 'woff' => 'font/woff', 'woff2' => 'font/woff2', 'otf' => 'font/otf' ]; $mime = $mimeMap[$ext] ?? 'application/octet-stream'; // 添加跨域头并输出内容 header("Access-Control-Allow-Origin: *"); // 或者指定你的域名,比如http://my-domain.com header("Content-Type: $mime"); echo $fontContent; ?>
第二步:替换爬取页面中的字体URL
把页面里的字体URL替换成代理脚本的地址:
$html = preg_replace('/http:\/\/jakartagrosir\.com\/fonts\/(.*?)/', '/font-proxy.php?url=http://jakartagrosir.com/fonts/$1', $html);
方案3:移除字体引用(最简单)
如果字体不影响你展示核心数据,直接把页面里的字体相关代码删掉就行,这样浏览器不会去请求目标网站的字体,自然不会触发CORS错误:
// 移除字体CSS链接 $html = preg_replace('/<link.*?href="http:\/\/jakartagrosir\.com\/fonts\/.*?".*?>/', '', $html); // 移除内联CSS中的字体规则 $html = preg_replace('/@font-face.*?\{.*?\}/s', '', $html);
最后提醒一句:爬取网站数据前,记得查看目标网站的robots.txt和使用条款,确保你的行为符合规定,避免不必要的法律风险。
内容的提问来源于stack exchange,提问作者CSM
相关产品推荐
相关产品推荐

