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

从AWS Dynamodb获取餐厅数据时JSON解析错误求助

技术求助:无法从AWS DynamoDB获取餐厅详情并展示

错误提示:Uncaught SyntaxError: Unexpected token '<', "<html> "... is not valid JSON at JSON.parse (<anonymous>)

使用JavaScript+HTML+Node.js开发网站,点击餐厅跳转详情页时,URL参数restaurant_name能正确携带,但无法加载对应餐厅数据,目标是成功从数据库获取并展示数据。

现有JS代码

function getOneRestaurant() {
    var response = "";
    var request = new XMLHttpRequest();
    var urlParams = new URLSearchParams(window.location.search);
    var restaurant_name = urlParams.get("restaurant_name");
    console.log(restaurant_name)

    // 错误:URL开头多了斜杠,导致请求路径错误
    request.open("GET", "/https://aba3bd.execute-api.us-east-1.amazonaws.com/restaurants/" + restaurant_name, true);
    request.setRequestHeader("Content-Type", "application/json");

    request.onload = function () {
        // 错误:重复解析JSON,且未判断请求状态
        info_array = JSON.parse(request.responseText);
        sessionStorage.setItem('restaurant__id', info_array[0].restaurant__id);
        sessionStorage.setItem('title', info_array[0].title);
        response = JSON.parse(request.responseText);
        console.log(response);
        
        var HTML = ""
        // 错误:若返回单个餐厅,循环逻辑不合理
        for (let i = 0; i < response.count; i++) {
            HTML += 
            '<img id="res_image" src="' + response.Items[i].image + '"' +
            'style="padding: 0 5% 0 5%; display: block; margin-left: auto; margin-right: auto; width: 88%; height: 500px; object-fit: cover;">' +
        '</div>'+        
        '<div id="restaurant_details" class="container featured-box" style="padding-bottom: 15%;">' +
            '<h1 id="res_name" style="width: 500px;">' + response.Items[i].restaurant_name + '</h1>'+                
            '<div style="padding-bottom: 50px; margin-bottom: -5rem;">' +
                '<span id="res_badge" style="background-color: #debc99; color: white;"'+ 
                    'class="badge badge-secondary float-left">'+                    
                    '<div id="res_cuisine" style="font-size:medium;">' + response.Items[i].cuisine + '</div>'+                
                '</span>'+                
                '<div class="line"> </div>'+            
            '</div>'+        
            '<div class="line" style="margin-top: 20px;margin-bottom: -5rem;">'+                
                '<!-- Booking button -->'+                
                '<button type="button" id="btn_review" class="btn btn-primary"'+ 
                    'style="background-color: #8d4843; border: none;" data-toggle="modal" data-target="#bookingForm">'+                    
                    '<i class="fa fa-pencil-square-o" style="font-size: 20px;"></i>Make a booking</button>'+        
                '<!-- Favourite button -->'+                
                '<div style="padding-left: 20px; display: inline;">'+                    
                    '<button type="button" id="btn_favourite" class="btn btn-primary"'+ 
                        'style="background-color: #8d4843; border: none;" onclick="add_or_delete_favourites()">'+                        
                        '<i class="fa-bookmark fa-solid"></i> Add to Favourites </button>'+                
                '</div>'+            
            '</div>'+        
            '<!-- Map Section -->'+            
            '<div class="card" style="width: 16rem; position: absolute; margin-left: 680px; margin-top: 29rem;">'+                
                '<iframe'+ 
                    'src="' + response.Items[i].map + '"'+ 
                    'width="400" height="350" style="border:0;" allowfullscreen="" loading="lazy"'+ 
                    'referrerpolicy="no-referrer-when-downgrade"></iframe>'+            
            '</div>'+            
            '<!-- About section -->'+            
            '<div style="margin-top: 80px; width: 100rem;font-size: medium; font-weight:lighter;">'+                
                '<p id="description"'+ 
                    'style="width: 1100px; border-bottom: 1px solid black; border-style: solid; border-top: none; border-left: none; border-right: none; padding-bottom: 20px; ">'+                    
                    response.Items[i].description + '</p>' +        
            '</div>'+        
            '<!-- Restaurant Information -->'+            
            '<div'+ 
                'style="width: 600px; height: 400px; border-bottom: 1px solid black;  border-style: solid; border-top: none; border-left: none; border-right: none; margin-bottom: -100px; ">'+        
                '<h2 style="color: #ff914d; font-size: x-large;">Address</h2>'+                
                '<p style="font-size: medium;">'+                
                response.Items[i].address +                
                '</p>'+                
                '<h2 style="color: #ff914d; font-size: x-large;"> Contact Details</h2>'+                
                '<p style="font-size: medium;">+' + response.Items[i].contact_number + '</p>'+                
                '<h2 style="color: #ff914d; font-size: x-large;">Operating hours</h2>'+                
                '<p style="font-size: medium;">Mondays to Fridays 9am to 6pm</p>'+        
            '</div>'+                
        '</div>'                
        };
        // 错误:DOM更新在onload函数外部,此时HTML尚未生成
        document.getElementById('restaurantinfo').innerHTML = HTML
    };

    request.send();
}

现有HTML代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Restaurant Information</title>
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
    <!-- Required scripts -->
    <!-- <script src="scripts/login_signup.js"></script>
    <script src="scripts/restaurant_filters.js"></script>
    <script src='scripts/restaurant_display.js'></script> -->

</head>
<style>
    ::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */
  color: black;
  opacity: 1; /* Firefox */
}
</style>
<body onload="setNavBar(); getOneRestaurant();" >

<div id="restaurantinfo">
<div>
    <img  id="res_image" src="images/restaurant_image.jpg"
        style="padding: 0 5% 0 5%; display: block; margin-left: auto; margin-right: auto; width: 88%; height: 500px; object-fit: cover;">
    </div>

    <div id='restaurant_details' class='container featured-box' style="padding-bottom: 15%;">
        <h1 id='res_name' style="width: 500px;">Paradise Dynasty</h1>
        <div style="padding-bottom: 50px; margin-bottom: -5rem;">
            <span id='res_badge' style="background-color: #debc99; color: white;"
                class="badge badge-secondary float-left">
                <div id='res_cuisine' style="font-size:medium;"> cuisine </div>
            </span>
            <div class="line"> </div>
        </div>

        <div class="line" style="margin-top: 20px;margin-bottom: -5rem;">
            <!-- Booking button -->
            <button type="button" id="btn_review" class="btn btn-primary"
                style="background-color: #8d4843; border: none;" data-toggle="modal" data-target="#bookingForm">
                <i class="fa fa-pencil-square-o" style="font-size: 20px;"></i>Make a booking</button>

            <!-- Favourite button -->
            <div style="padding-left: 20px; display: inline;">
                <button type="button" id="btn_favourite" class="btn btn-primary"
                    style="background-color: #8d4843; border: none;" onclick="add_or_delete_favourites()">
                    <i class="fa-bookmark fa-solid"></i> Add to Favourites </button>
            </div>
        </div>

        <!-- Map Section -->
        <div class="card" style="width: 16rem; position: absolute; margin-left: 680px; margin-top: 29rem;">
            <iframe
                src="https://www.google.com/maps/embed?"
                width="400" height="350" style="border:0;" allowfullscreen="" loading="lazy"
                referrerpolicy="no-referrer-when-downgrade"></iframe>
        </div>
        <!-- About section -->
        <div style="margin-top: 80px; width: 100rem;font-size: medium; font-weight:lighter;">
            <p id='description'
                style="width: 1100px; border-bottom: 1px solid black; border-style: solid; border-top: none; border-left: none; border-right: none; padding-bottom: 20px; ">
                Dining at Paradise Dynasty is akin to taking a step back to imperial China. Marvel at the opulence </p>

        </div>

        <!-- Restaurant Information -->
        <div
            style="width: 600px; height: 400px; border-bottom: 1px solid black;  border-style: solid; border-top: none; border-left: none; border-right: none; margin-bottom: -100px; ">

            <h2 style="color: #ff914d; font-size: x-large;">Address</h2>
            <p style="font-size: medium;">
                435 Orchard Rd, #01-18 Wisma Atria, Singapore 238877435 Orchard Rd, #01-18 Wisma Atria, Singapore 238877
            </p>
            <h2 style="color: #ff914d; font-size: x-large;"> Contact Details</h2>
            <p style="font-size: medium;">+65 6487 6489</p>
            <h2 style="color: #ff914d; font-size: x-large;">Operating hours</h2>
            <p style="font-size: medium;">Mondays to Fridays 9am to 6pm</p>

        </div>
        

    </div>
</div>
    <!-- About -->
    <div style="font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;"
        class="container-fluid about">
        <div class="row">
            <div class="col-md-2 offset-md-2">
                <h1>HEARTY EATS<h1>
            </div>
            <div class="col-md-6 justifytext" style="font-size:medium;">Hearty Eats is a restaurant reservation website
                created to provide
                customers with a fuss free dining experience. Book a restaurant anytime, anywhere. Choose a restaurant,
                select a date and time, and you're good to go!</div>
        </div>
    </div>
    

</body>

</html>

问题修复方案

1. 修正API请求URL

请求URL开头多了斜杠,导致浏览器把它当成相对路径,请求到自己的服务器返回HTML页面,这就是JSON解析报错的根源。把URL改为:

request.open("GET", "https://aba3bd.execute-api.us-east-1.amazonaws.com/restaurants/" + restaurant_name, true);

2. 调整DOM更新位置

把document.getElementById('restaurantinfo').innerHTML = HTML移到request.onload函数内部、数据处理完成之后,确保HTML生成完毕再更新DOM。

3. 优化JSON解析逻辑

去掉重复的JSON解析,先判断请求状态码是否为200,再用try-catch包裹解析逻辑,避免解析失败直接阻断代码:

request.onload = function () {
    if (request.status === 200) {
        try {
            response = JSON.parse(request.responseText);
            // 后续数据处理与HTML生成逻辑
        } catch (e) {
            console.error("JSON解析失败", e);
        }
    } else {
        console.error("请求失败,状态码:", request.status);
    }
};

4. 修正循环逻辑

如果API返回的是单个餐厅数据,直接取response.Items[0]即可,不需要循环遍历:

var restaurant = response.Items[0];
// 后续所有response.Items[i]替换为restaurant

5. 移除冗余请求头

GET请求不需要设置Content-Type请求头,直接删除该行代码。

6. 添加网络错误处理

监听请求错误事件,处理网络异常情况:

request.onerror = function() {
    console.error("网络请求出错");
};

修正后的完整JS代码

function getOneRestaurant() {
    var request = new XMLHttpRequest();
    var urlParams = new URLSearchParams(window.location.search);
    var restaurant_name = urlParams.get("restaurant_name");
    console.log(restaurant_name)

    // 修正URL,去掉开头的斜杠
    request.open("GET", "https://aba3bd.execute-api.us-east-1.amazonaws.com/restaurants/" + restaurant_name, true);

    request.onload = function () {
        if (request.status === 200) {
            try {
                var response = JSON.parse(request.responseText);
                console.log(response);
                
                // 单个餐厅直接取Items[0]
                var restaurant = response.Items[0];
                var HTML = "";

                HTML += 
                '<div>'+
                '<img id="res_image" src="' + restaurant.image + '"' +
                'style="padding: 0 5% 0 5%; display: block; margin-left: auto; margin-right: auto; width: 88%; height: 500px; object-fit: cover;">' +
            '</div>'+        
            '<div id="restaurant_details" class="container featured-box" style="padding-bottom: 15%;">' +
                '<h1 id="res_name" style="width: 500px;">' + restaurant.restaurant_name + '</h1>'+                
                '<div style="padding-bottom: 50px; margin-bottom: -5rem;">' +
                    '<span id="res_badge" style="background-color: #debc99; color: white;"'+ 
                        'class="badge badge-secondary float-left">'+                    
                        '<div id="res_cuisine" style="font-size:medium;">' + restaurant.cuisine + '</div>'+                
                    '</span>'+                
                    '<div class="line"> </div>'+            
                '</div>'+        
                '<div class="line" style="margin-top: 20px;margin-bottom: -5rem;">'+                
                    '<!-- Booking button -->'+                
                    '<button type="button" id="btn_review" class="btn btn-primary"'+ 
                        'style="background-color: #8d4843; border: none;" data-toggle="modal" data-target="#bookingForm">'+                    
                        '<i class="fa fa-pencil-square-o" style="font-size: 20px;"></i>Make a booking</button>'+        
                    '<!-- Favourite button -->'+                
                    '<div style="padding-left: 20px; display: inline;">'+                    
                        '<button type="button" id="btn_favourite" class="btn btn-primary"'+ 
                            'style="background-color: #8d4843; border: none;" onclick="add_or_delete_favourites()">'+                            
                            '<i class="fa-bookmark fa-solid"></i> Add to Favourites </button>'+                
                    '</div>'+            
                '</div>'+        
                '<!-- Map Section -->'+            
                '<div class="card" style="width: 16rem; position: absolute; margin-left: 680px; margin-top: 29rem;">'+                
                    '<iframe'+ 
                        'src="' + restaurant.map + '"'+ 
                        'width="400" height="350" style="border:0;" allowfullscreen="" loading="lazy"'+ 
                        'referrerpolicy="no-referrer-when-downgrade"></iframe>'+            
                '</div>'+            
                '<!-- About section -->'+            
                '<div style="margin-top: 80px; width: 100rem;font-size: medium; font-weight:lighter;">'+                
                    '<p id="description"'+ 
                        'style="width: 1100px; border-bottom: 1px solid black; border-style: solid; border-top: none; border-left: none; border-right: none; padding-bottom: 20px; ">'+                    
                        restaurant.description + '</p>' +        
                '</div>'+        
                '<!-- Restaurant Information -->'+            
                '<div'+ 
                    'style="width: 600px; height: 400px; border-bottom: 1px solid black;  border-style: solid; border-top: none; border-left:
相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 13:25:19