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

AJAX请求返回SyntaxError: Unexpected token '<'问题排查求助

问题:AJAX调用PHP文件返回PHP源码导致JSON解析错误

我正在编写一个JavaScript函数,从GeoJSON文件中根据国家名称匹配对应的JSON对象并提取国家代码,再将该代码作为参数调用API获取国家信息并展示在模态框中。但出现错误SyntaxError: Unexpected token '<', "<?php,无法定位问题所在,怀疑该错误与countryInfo.php的AJAX调用有关。


相关代码

JavaScript代码

let code

$('#innerSelect').on('change', async () => {     //Handles changing the country select.
  await addCountryBorder($('#innerSelect').val())  /* Calls function that adds country border to map */
  countryInfo($('#innerSelect').val())

  const result = await $.ajax({
    url: 'libs/php/getCoordsFromCountryName.php',
    type: 'GET',
    dataType: 'json',
    data: { countryName: $('#innerSelect').val() }
  })

  if (result.status.name == 'ok') {
    const { lat, lng } = result.data[0].geometry
    map.panTo(new L.LatLng(lat, lng))
  }
});

/* Function responsible for adding border to a given country and grabbing country code*/
async function addCountryBorder (countryName) {
  const result = await $.ajax({
    url: 'assets/geojson/countryBorders.geo.json',
    type: 'GET',
    dataType: 'json',
    data: {}
  })

  const features = result.features

  const countryFeature = findFeatureFromName(countryName)

  if (!countryFeature) return

  if (border) map.removeLayer(border)

  border = new L.geoJSON(countryFeature.geometry, {
    style: { color: '#006600' }
  }).addTo(map)

  map.panTo(border.getBounds().getCenter())
  map.fitBounds(border.getBounds())

  console.log(countryFeature)
}


function countryInfo(countryName) {
        $.ajax({
        url: "assets/geojson/countryBorders.geo.json",
        type: "GET",
        dataType: "json",
        data: {
            
        },
        success: function(result) {
            let features = result["features"];

            let countryFeature = findFeatureFromName(countryName);
            countryCode = JSON.stringify(countryFeature.properties.iso_a2)

            
            console.log(countryCode)
            
        $.ajax({
        url: "assets/php/countryInfo.php",
        type: 'POST',
        dataType: 'json',
        data: {
            country: countryCode,
        },
        success: function(result) {

                console.log(JSON.stringify(result));

                if (result.status.name == "ok") {

                $('#continent').html(result['data'][0]['continentName']);
                $('#capital').html(result['data'][0]['capital']);
                $('#countryName').html(result['data'][0]['countryName']);
                $('#population').html(formattedPopulation);
                $('#currencyCode').html(result['data'][0]['currencyCode']);


                }
        },
        error: function(jqXHR, textStatus, errorThrown) {
            console.log(errorThrown);
        }
    });
}
  });
}

PHP代码

<?php

    // remove for production

    ini_set('display_errors', 'On');
    error_reporting(E_ALL);

    $executionStartTime = microtime(true);

    $url='http://api.geonames.org/countryInfoJSON?formatted=true&country=' . $_REQUEST['country'] . '&username=username&style=full';

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_URL,$url);

    $result=curl_exec($ch);

    curl_close($ch);

    $decode = json_decode($result,true);    

    $output['status']['code'] = "200";
    $output['status']['name'] = "ok";
    $output['status']['description'] = "success";
    $output['status']['returnedIn'] = intval((microtime(true) - $executionStartTime) * 1000) . " ms";
    $output['data'] = $decode['geonames'];
    
    header('Content-Type: application/json; charset=UTF-8');

    echo json_encode($output); 

?>

HTML代码

<!-- The Modal -->
  <div class="modal fade" id="myModal">
    <div class="modal-dialog">
      <div class="modal-content">
      
        <!-- Modal Header -->
        <div class="modal-header">
          <h4 class="modal-title">Information</h4>
           <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
        </div>        
        <!-- Modal body -->
        <div class="modal-body">
          <h6 id="countryName" class="modal-sub-header"></h6>
          <hr>
          <ul class="dem">
            <li class="listItem">Capital City: <span class="test" id="capital"></span></li>
            <li class="listItem">Continent: <span class="test" id="continent"></span></li>
            <li class="listItem">Population: <span class="test" id="population"></span></li>
            <li class="listItem">Currency: <span class="test" id="currencyCode"></span></li>
            <li class="listItem">Area (km<sup>2</sup>): <span class="test" id="area"></span></li>
          </ul>
        </div>          
      </div>
    </div>
  </div>

控制台错误信息

SyntaxError: Unexpected token '<', "<?php

    //"... is not valid JSON
    at parse (<anonymous>)
    at ajaxConvert (jquery-3.5.1.js:9260:19)
    at done (jquery-3.5.1.js:9736:15)
    at XMLHttpRequest.<anonymous> (jquery-3.5.1.js:10047:9)

错误分析与解决步骤

错误核心原因

这个错误说明AJAX请求没有拿到预期的JSON数据,反而拿到了PHP文件的源码(或带HTML标签的错误页面),导致JSON解析失败,常见触发点:

  1. 服务器未配置PHP解析:PHP文件被当作纯文本返回,而非执行后输出JSON
  2. 请求路径错误:countryInfo.php的URL写错,服务器返回404 HTML页面
  3. PHP代码执行出错:PHP运行时输出了带HTML的错误信息,而非合法JSON
  4. 参数传递错误:JS传递的国家代码格式不对,导致PHP调用第三方API失败,进而输出异常内容

逐个排查解决

  1. 验证PHP文件能否正常执行
    直接在浏览器地址栏输入http://你的域名/assets/php/countryInfo.php?country=CN,如果显示PHP源码,说明服务器没配置PHP环境(比如用了纯静态服务器),需要换成XAMPP/WAMP这类支持PHP的环境,或者调整服务器配置。

  2. 检查AJAX请求路径
    打开浏览器开发者工具的「网络」面板,查看countryInfo.php请求的状态码:

    • 若为404:说明路径写错,核对文件实际位置和AJAX里的url是否一致
    • 若为200但返回源码:回到第一步解决PHP解析问题
  3. 修正国家代码传递逻辑
    JS里用JSON.stringify(countryFeature.properties.iso_a2)会把代码变成带双引号的字符串(比如"CN"),传到PHP后拼接的API URL会变成country="CN",导致第三方API返回错误。改成直接传原始值:

    // 去掉JSON.stringify,直接取原始值
    countryCode = countryFeature.properties.iso_a2
    
  4. 优化PHP参数处理
    PHP里用$_REQUEST不够严谨,POST请求直接用$_POST,同时对参数做URL编码避免拼接错误:

    // 替换原有的URL拼接代码
    $country = urlencode($_POST['country']);
    $url="http://api.geonames.org/countryInfoJSON?formatted=true&country={$country}&username=你的实际用户名&style=full";
    

    注意:把代码里的username=username换成你在GeoNames注册的真实用户名。

  5. 排查PHP执行错误
    在PHP文件里添加调试代码,查看curl请求是否成功:

    $result=curl_exec($ch);
    // 临时添加,查看curl返回的内容
    var_dump($result);
    curl_close($ch);
    

    如果返回错误信息,根据提示修复(比如GeoNames用户名无效、API请求频率超限等)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 14:50:39