Next.js – 如何返回 JSON 而不是预渲染的 HTML 页面

huangapple go评论57阅读模式
英文:

Next.js - How to return JSON instead of HTML pre-rendered page

问题

这是你要翻译的内容:

"I have a page which shows some basic data. That page is available under the URL /markets/[market].

In this page I want to load some current information about this market with an ajax request.
This is the code of this page:

import useSWR from "swr";
import { useRouter } from "next/router";
import { useState, useEffect } from 'react';

const fetcher = (url) => fetch(url).then((res) => res.json());

export default function Market(props) {
    const router = useRouter();
    const [market,setMarket] = useState(null);

    useEffect(() => {
        if(props.market) {
            setMarket(JSON.parse(props.market));
            console.log(JSON.parse(props.market));
        }
    },[props]);


    const { data, error } = useSWR(
        '/markets/data/' + router.query.market,
        fetcher
    );

    if (error) {
        console.log(error);
        return <div>Failed to load.</div>;
    }
    if (!data) return <div>Loading...</div>;

    return (
        <div>
            ...
        </div>
    )
}

As you can see the data is being fetched from /markets/data/[market].
I already managed, that this page gets no default layout applied. So the output is json format:

Next.js – 如何返回 JSON 而不是预渲染的 HTML 页面

But the output looks like JSON-format but is HTML due to server pre-rendering.

Next.js – 如何返回 JSON 而不是预渲染的 HTML 页面

How can I switch the output to JSON instead of HTML.

For completness here is the code of the page /markets/data/[market].

import dynamic from 'next/dynamic';
import { useRouter } from "next/router";
import { useState, useEffect } from 'react';

export default function MarketData(props) {
    const router = useRouter();
    const [prices, setPrices] = useState(null);

    useEffect(() => {
        if(props.prices) {
            setPrices(JSON.parse(props.prices));
            console.log(JSON.parse(props.prices));
        }
    },[props]);

  return JSON.stringify({
    market: {
        name: router.query.market,
        prices: props.prices
    }
  });
}

export async function getServerSideProps(context) {
    // fetch some stuff and return it
    return {
        props: { 
            prices: JSON.stringify(got),
        }
    };
}
英文:

First I need to say, that I'm new to Next.js.
I'm sure it is a simple question, but perhaps I have taken the wrong approach. If so, please let me know. I already googled some stuff, but nothing provided me a working solution.

I have a page which shows some basic data. That page is available under the URL /markets/[market].

In this page I want to load some current information about this market with an ajax request.
This is the code of this page:

import useSWR from "swr";
import { useRouter } from "next/router";
import { useState, useEffect } from 'react';

const fetcher = (url) => fetch(url).then((res) => res.json());

export default function Market(props) {
    const router = useRouter();
    const [market,setMarket] = useState(null);

    useEffect(() => {
        if(props.market) {
            setMarket(JSON.parse(props.market));
            console.log(JSON.parse(props.market));
        }
    },[props]);

    
    const { data, error } = useSWR(
        '/markets/data/' + router.query.market,
        fetcher
    );

    if (error) {
        console.log(error);
        return <div>Failed to load.</div>;
    }
    if (!data) return <div>Loading...</div>;

    return (
        <div>
            ...
        </div>
    )
}

As you can see the data is being fetched from /markets/data/[market].
I already managed, that this page gets no default layout applied. So the output is json format:

Next.js – 如何返回 JSON 而不是预渲染的 HTML 页面

But the output looks like JSON-format but is HTML due to server pre-rendering.

Next.js – 如何返回 JSON 而不是预渲染的 HTML 页面

How can I switch the output to JSON instead of HTML.

For completness here is the code of the page /markets/data/[market].

import dynamic from 'next/dynamic';
import { useRouter } from "next/router";
import { useState, useEffect } from 'react';

export default function MarketData(props) {
    const router = useRouter();
    const [prices, setPrices] = useState(null);

    useEffect(() => {
        if(props.prices) {
            setPrices(JSON.parse(props.prices));
            console.log(JSON.parse(props.prices));
        }
    },[props]);

  return JSON.stringify({
    market: {
        name: router.query.market,
        prices: props.prices
    }
  });
}

export async function getServerSideProps(context) {
    // fetch some stuff and return it
    return {
        props: { 
            prices: JSON.stringify(got),
        }
    };
}

答案1

得分: 2

这是解决我的问题的解决方案:

export default function MarketData(props) {
    return (
        <></>
    )
}

export const getServerSideProps = async ({ req, res, resolvedUrl }) => {
    ...
    res.setHeader("Content-Type", "application/json");
    res.write('{"market": "' + market + '", "prices": ' + JSON.stringify(got) + '}');
    res.end();
    return {
        props: {},
    };
}

将内容类型设置为 application/json 并使用 write 返回数据。

重要提示: 即使在函数的最后没有到达这段代码,你仍需要返回一个 JavaScript 对象!

英文:

This is the solution to my issue:

export default function MarketData(props) {
    return (
        &lt;&gt;&lt;/&gt;
    )
}

export const getServerSideProps = async ({ req, res, resolvedUrl }) =&gt; {
    ...
    res.setHeader(&quot;Content-Type&quot;, &quot;application/json&quot;);
    res.write(&#39;{\&quot;market\&quot;: &quot;&#39; + market + &#39;&quot;, &quot;prices&quot;: &#39; + JSON.stringify(got) + &#39;}&#39;);
    res.end();
    return {
        props: {},
    };
}

Set the content type to application/json and return the data with write.

IMPORTANT: You need to return an Javascript object even this code is not beeing reached at the end of the function!

huangapple
  • 本文由 发表于 2023年5月29日 17:08:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76356012.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定