JS调用PHP接口报错:Unexpected token '<'问题求助
问题描述
通过JS的fetch调用PHP接口时,执行fetch环节立即抛出错误:Error: Unexpected token '<'。尝试在fetch后添加console.log无法执行,移除JS中的<>标签也未解决问题,附上完整代码请求排查。
相关代码
index.php
<?php session_start(); use GuzzleHttp\Client; require 'vendor/autoload.php'; header('Content-Type: application/json'); $apiKey = 'API_KEY'; $model = 'gpt-3.5-turbo'; $endpoint = 'https://api.openai.com/v1/chat/completions'; $userMessage = trim($_POST['message']); if (!isset($_SESSION['chat_history'])) { $_SESSION['chat_history'] = []; } if (!empty($userMessage)) { $_SESSION['chat_history'][] = ['role' => 'user', 'content' => $userMessage]; } $_SESSION['chat_history'] = array_filter($_SESSION['chat_history'], function($message) { return !empty($message['content']); }); $client = new Client(); try { $response = $client->post($endpoint, [ 'headers' => [ 'Authorization' => 'Bearer ' . $apiKey, 'Content-Type' => 'application/json', ], 'json' => [ 'model' => $model, 'messages' => $_SESSION['chat_history'], 'max_tokens' => 50, ], ]); $body = $response->getBody(); $data = json_decode($body, true); if (isset($data['choices'][0]['message']['content'])) { $botMessage = $data['choices'][0]['message']['content']; $_SESSION['chat_history'][] = ['role' => 'assistant', 'content' => $botMessage]; echo json_encode(['message' => $botMessage]); } else { echo json_encode(['error' => 'No response from ChatGPT']); } } catch (Exception $e) { echo json_encode(['error' => $e->getMessage()]); } ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); ?>
script.js
document.getElementById('chatForm').addEventListener('submit', function (e) { e.preventDefault(); const userMessage = document.getElementById('userMessage').value; const chatHistory = document.getElementById('chatHistory'); chatHistory.innerHTML += `<p><strong>User: </strong> ${userMessage}</p>`; document.getElementById('userMessage').value = ''; fetch('index.php', { // fetching method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: 'message=' + encodeURIComponent(userMessage) }) .then(response => response.json()) .then(data => { if (data.message) { chatHistory.innerHTML += `<p><strong>Bot:</strong> ${data.message}</p>`; console.log("Gone!") } else { chatHistory.innerHTML += `<p><strong>Error:</strong> ${data.error}</p>`; } chatHistory.scrollTop = chatHistory.scrollHeight; }) .catch(error => { chatHistory.innerHTML += `<p>Error: ${error.message}</p>`; chatHistory.scrollTop = chatHistory.scrollHeight; }); });
问题原因及解决办法
核心原因
Unexpected token '<' 说明PHP接口返回的不是合法JSON,而是HTML内容(比如PHP错误提示、警告信息)。你把ini_set('display_errors', 1);放在代码末尾,当PHP执行过程中出现错误时,错误信息会在header('Content-Type: application/json');之后输出,导致返回内容混有HTML格式的错误提示,破坏了JSON结构。
具体问题点
- 错误配置位置错误:
ini_set和error_reporting放在代码最后,无法提前捕获初始化阶段的错误(比如Guzzle未安装、vendor/autoload.php不存在),这些错误会以HTML形式输出,和JSON内容混合。 - 可能存在依赖缺失:如果
vendor/autoload.php不存在(未执行composer install安装Guzzle),PHP会直接输出致命错误的HTML页面,导致fetch解析JSON失败。
解决步骤
- 调整错误配置位置:把错误配置代码移到PHP最开头,确保错误能被正确捕获或输出格式可控:
<?php ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); session_start(); use GuzzleHttp\Client; require 'vendor/autoload.php'; header('Content-Type: application/json'); // 后续代码不变
- 检查依赖安装:确认已执行
composer require guzzlehttp/guzzle,确保vendor/autoload.php存在。如果未安装,先执行该命令。 - 调试返回内容:在fetch的
then里先打印原始响应,确认返回的具体内容:
fetch('index.php', { // 原有配置不变 }) .then(response => { // 先打印原始响应文本,排查返回内容 return response.text().then(text => { console.log('Raw response:', text); return JSON.parse(text); }); }) // 后续then/catch逻辑不变
通过打印原始响应,能快速定位是哪部分错误导致的HTML输出。
内容的提问来源于stack exchange,提问作者Software Engineer
相关产品推荐
相关产品推荐

