从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:
相关产品推荐
相关产品推荐

