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

在cPanel服务器使用PHP获取JSON数据时遭遇403错误求助

问题排查:跨域请求403与JSON解析错误

场景复现

我在index.html中嵌入了以下JavaScript代码,用来调用/data.php获取JSON数据:

async function fetchCelebritiesData() {
  try {
    const response = await fetch('/data.php');
    const data = await response.json();
    return data;
  } catch (error) {
    console.error('Error fetching data:', error);
    return [];
  }
}

对应的PHP文件负责校验请求来源域名,并读取data.json返回数据,代码如下:

<?php
// 校验请求来源域名
$allowedOrigins = array("example.com", "www.example.com");

$origin = $_SERVER['HTTP_ORIGIN'] ?? ''; // 获取请求中的HTTP_ORIGIN

if (in_array($origin, $allowedOrigins)) {
    header("Access-Control-Allow-Origin: $origin");
} else {
    header("HTTP/1.1 403 Forbidden");
    exit;
}

// 读取并输出JSON数据
$data = file_get_contents("data.json");
header("Content-Type: application/json");
echo $data;
?>

当前遇到的问题:

  • 前端返回403 Forbidden错误
  • 控制台提示SyntaxError: Unexpected end of JSON input
  • PHP日志显示Undefined index: HTTP_ORIGIN
  • 已确认PHP、JSON文件及文件夹权限为644,无权限问题

问题原因分析

  1. HTTP_ORIGIN未定义的触发场景

    • 当请求是同域请求时,浏览器不会发送HTTP_ORIGIN请求头,导致$_SERVER['HTTP_ORIGIN']不存在,触发日志报错;同时空字符串不在允许的域名列表中,直接返回403。
    • 本地开发环境(如localhost或127.0.0.1)的请求,部分浏览器也不会携带HTTP_ORIGIN头。
  2. JSON解析错误的关联原因
    PHP返回403状态码时,没有输出任何JSON内容,前端尝试解析空内容为JSON,自然触发Unexpected end of JSON input错误。


解决方案

方案1:兼容同域与本地开发请求

修改PHP代码,处理HTTP_ORIGIN不存在的情况,并补充本地开发域名到允许列表:

<?php
$allowedOrigins = array("example.com", "www.example.com", "localhost", "127.0.0.1");

// 获取请求来源,兼容无ORIGIN头的情况
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';

// 同域请求直接允许;跨域请求校验域名
if (empty($origin) || in_array(parse_url($origin, PHP_URL_HOST), $allowedOrigins)) {
    // 同域时设置为当前请求的Host,跨域时用请求的Origin
    $allowOrigin = empty($origin) ? $_SERVER['HTTP_HOST'] : $origin;
    header("Access-Control-Allow-Origin: $allowOrigin");
} else {
    header("HTTP/1.1 403 Forbidden");
    exit;
}

// 读取并输出JSON数据
$data = file_get_contents("data.json");
header("Content-Type: application/json");
echo $data;
?>

方案2:前端增加状态码校验

在JavaScript的fetch逻辑中,先判断响应状态是否正常,再解析JSON,避免空内容解析报错:

async function fetchCelebritiesData() {
  try {
    const response = await fetch('/data.php');
    // 先检查响应状态码是否正常
    if (!response.ok) {
      throw new Error(`请求失败,状态码:${response.status}`);
    }
    const data = await response.json();
    return data;
  } catch (error) {
    console.error('获取数据出错:', error);
    return [];
  }
}

额外注意事项

  • 本地开发时,确保allowedOrigins包含localhost或127.0.0.1,否则本地请求会被拦截。
  • 检查data.json文件是否存在,且内容是合法的JSON格式,避免后续返回无效JSON。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 10:01:03