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

React Router 6教程中调用MirageJS接口遇JSON解析错误求助

React + MirageJS 请求返回HTML而非JSON的错误排查

问题描述

我在学习Scrimba的React与React Router 6教程时,复制教程代码后遇到数据请求错误。错误信息为:
67:1 Uncaught (in promise) SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON
触发位置在Vans.jsx的第9行.then(data => setVans(data.vans))处。

Vans.jsx 代码

import React from 'react'
import { Link } from 'react-router-dom'

export default function Vans() {
    const [vans, setVans] = React.useState([])
    React.useEffect(() => {
        fetch("/api/vans")
            .then(res => res.json())
            .then(data => setVans(data.vans))
    }, [])

    const vanElements = vans.map(van => (
        <div key={van.id} className="van-tile">
            <Link to={`/vans/${van.id}`}>
                <img src={van.imageUrl} />
                <div className="van-info">
                    <h3>{van.name}</h3>
                    <p>${van.price}<span>/day</span></p>
                </div>
                <i className={`van-type ${van.type} selected`}>{van.type}</i>
            </Link>
        </div>
    ))

    return (
        <div className="van-list-container">
            <h1>Explore our van options</h1>
            <div className="van-list">
                {vanElements}
            </div>
        </div>
    )
}

server.js(MirageJS模拟接口)代码

import { createServer, Model } from "miragejs"


createServer({
    models: {
        vans: Model,
    },

    seeds(server) {
        server.create("van", { id: "1", name: "Modest Explorer", price: 60, description: "The Modest Explorer is a van designed to get you out of the house and into nature. This beauty is equipped with solar panels, a composting toilet, a water tank and kitchenette. The idea is that you can pack up your home and escape for a weekend or even longer!", imageUrl: "https://assets.scrimba.com/advanced-react/react-router/modest-explorer.png", type: "simple" })
        server.create("van", { id: "2", name: "Beach Bum", price: 80, description: "Beach Bum is a van inspired by surfers and travelers. It was created to be a portable home away from home, but with some cool features in it you won't find in an ordinary camper.", imageUrl: "https://assets.scrimba.com/advanced-react/react-router/beach-bum.png", type: "rugged" })
        server.create("van", { id: "3", name: "Reliable Red", price: 100, description: "Reliable Red is a van that was made for travelling. The inside is comfortable and cozy, with plenty of space to stretch out in. There's a small kitchen, so you can cook if you need to. You'll feel like home as soon as you step out of it.", imageUrl: "https://assets.scrimba.com/advanced-react/react-router/reliable-red.png", type: "luxury" })
        server.create("van", { id: "4", name: "Dreamfinder", price: 65, description: "Dreamfinder is the perfect van to travel in and experience. With a ceiling height of 2.1m, you can stand up in this van and there is great head room. The floor is a beautiful glass-reinforced plastic (GRP) which is easy to clean and very hard wearing. A large rear window and large side windows make it really light inside and keep it well ventilated.", imageUrl: "https://assets.scrimba.com/advanced-react/react-router/dreamfinder.png", type: "simple" })
        server.create("van", { id: "5", name: "The Cruiser", price: 120, description: "The Cruiser is a van for those who love to travel in comfort and luxury. With its many windows, spacious interior and ample storage space, the Cruiser offers a beautiful view wherever you go.", imageUrl: "https://assets.scrimba.com/advanced-react/react-router/the-cruiser.png", type: "luxury" })
        server.create("van", { id: "6", name: "Green Wonder", price: 70, description: "With this van, you can take your travel life to the next level. The Green Wonder is a sustainable vehicle that's perfect for people who are looking for a stylish, eco-friendly mode of transport that can go anywhere.", imageUrl: "https://assets.scrimba.com/advanced-react/react-router/green-wonder.png", type: "rugged" })
    },

    routes() {
        this.namespace = "api"

        this.get("/vans", (schema, request) => {
            return schema.vans.all()
        })
        
        this.get("/vans/:id", (schema, request) => {
            const id = request.params.id
            return schema.vans.find(id)
        })
    }
})

问题原因与解决方案

这个错误的核心是:fetch("/api/vans")返回的不是预期的JSON数据,而是HTML页面(通常是404错误页面的<!DOCTYPE>内容),说明MirageJS的模拟接口没有拦截到请求,或者根本没启动。

1. 最可能的原因:server.js未被项目入口文件引入

MirageJS需要在应用启动时初始化,必须在React项目的入口文件(比如index.js、main.jsx或App.jsx)中导入server.js,否则MirageJS的模拟服务器不会启动,请求会直接发送到开发服务器,返回404的HTML页面。

解决办法:
在你的项目入口文件顶部添加导入语句:

import './server.js'

确保路径和server.js的实际位置匹配。

2. 额外验证与调试步骤

如果导入后问题仍存在,可以在fetch请求中添加调试代码,确认响应内容:

React.useEffect(() => {
    fetch("/api/vans")
        .then(res => {
            console.log("响应状态:", res.status)
            // 先获取文本内容,确认是HTML还是JSON
            return res.text()
        })
        .then(text => {
            console.log("响应内容:", text)
            try {
                const data = JSON.parse(text)
                setVans(data.vans)
            } catch (err) {
                console.error("解析JSON失败:", err)
            }
        })
        .catch(err => console.error("请求错误:", err))
}, [])

通过控制台输出可以明确看到返回的是HTML还是JSON,进一步定位问题。

3. 其他可能的小问题

  • 检查server.js中的this.namespace = "api"是否和请求路径/api/vans匹配(你的代码中这部分是正确的)。
  • 确认MirageJS已正确安装:执行npm install miragejs或yarn add miragejs确保依赖存在。

内容的提问来源于stack exchange,提问作者Vicente Antonio G. Reyes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 02:50:38