You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CORS预检拦截API请求求助:WordPress主题跨域调用DVLA API失败

解决WordPress子主题中跨域API请求的CORS问题

问题详情

用标准HTML、PHP、JavaScript制作WordPress子主题时,调用英国DVLA车辆查询API(https://driver-vehicle-licensing.api.gov.uk/vehicle-enquiry/v1/vehicles)遇到CORS拦截。关闭Chrome安全限制后,函数逻辑能正常返回车辆详情,但正常模式下控制台报错:

"Failed preflight check, access-control-allow-origin header is missing"

明确这是跨域问题,但尝试添加access-control-allow-origin响应头后毫无效果,本地MAMP服务器、生产服务器甚至单HTML文件中都存在该问题。

前端请求代码(来自front-page.php):

<script>
function submitReg() {
    
    var url = "https://driver-vehicle-licensing.api.gov.uk/vehicle-enquiry/v1/vehicles";
    var xhr = new XMLHttpRequest();
    xhr.open("POST", url);
    xhr.setRequestHeader("x-api-key", "APIKEYPLACEHOLDER");
    xhr.setRequestHeader("Content-Type", "application/json");

    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4){
            console.log(xhr.status);
            console.log(xhr.responseText);
        }
    };

    var reg = document.getElementById("inputReg");
    var data = JSON.stringify({"registrationNumber": reg.value});
    xhr.send(data);
}
</script>

已尝试但无效的方法

  1. 修改.htaccess文件(请求域名为example.com):
# BEGIN WordPress
# The directives (lines) between "BEGIN WordPress" and "END WordPress" are
# dynamically generated, and should only be modified via WordPress filters.
# Any changes to the directives between these markers will be overwritten.

Header set Access-Control-Allow-Origin "example.com"
Header set Access-Control-Allow-Credentials true
Header set Access-Control-Allow-Methods "POST, GET"


# END WordPress
  1. 在header.php和front-page.php顶部添加PHP头信息:
<?php header('Access-Control-Allow-Origin: *'); ?>

正确解决方案:后端代理

前端直接请求第三方API时,对方服务器未配置允许你的域名跨域,此时在自己服务器加CORS头完全无效——必须通过后端代理转发请求。

步骤1:创建代理PHP文件

在WordPress子主题目录下新建proxy-vehicle-api.php,代码如下:

<?php
// 允许你的前端域名跨域(替换为实际域名)
header("Access-Control-Allow-Origin: https://example.com");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Allow-Headers: Content-Type");

// 获取前端发送的POST数据
$data = file_get_contents('php://input');

// 初始化cURL请求
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://driver-vehicle-licensing.api.gov.uk/vehicle-enquiry/v1/vehicles");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// 携带API密钥和请求头
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    "x-api-key: 你的真实API密钥", // 替换为你的API密钥
    "Content-Type: application/json"
));

// 执行请求并获取响应
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

// 将响应返回给前端
http_response_code($httpCode);
echo $response;

curl_close($ch);
?>

步骤2:修改前端请求地址

把前端JS中的请求URL改成代理文件的路径,示例:

<script>
function submitReg() {
    // 替换为你的代理文件实际路径
    var url = "/wp-content/themes/你的子主题文件夹/proxy-vehicle-api.php";
    var xhr = new XMLHttpRequest();
    xhr.open("POST", url);
    xhr.setRequestHeader("Content-Type", "application/json");

    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4){
            console.log(xhr.status);
            console.log(xhr.responseText);
        }
    };

    var reg = document.getElementById("inputReg");
    var data = JSON.stringify({"registrationNumber": reg.value});
    xhr.send(data);
}
</script>

注意事项

  • 确保你的服务器已开启cURL扩展
  • API密钥放在后端,避免前端泄露
  • 如果需要携带Cookie等凭证,需调整Access-Control-Allow-Credentials并在前端请求中设置withCredentials: true

内容的提问来源于stack exchange,提问作者user3512002

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 13:50:28