将 Next.js 应用程序部署到 Vercel 时出现无效的 json 响应正文错误

时间:2021-05-18 06:21:35

标签: json deployment next.js vercel

应用程序在本地构建良好,可在本地生产服务器 + 开发服务器上运行。 用于获取数据的 api 工作正常。

产生错误的代码

export const getStaticProps = async () => {
    const resp = await fetch(
        'https://cdn-api.co-vin.in/api/v2/admin/location/states',
        {
            headers: {
                'User-Agent': '*',
            }, //this is required by api provider
        }
    );
    const data = await resp.json();
    //console.log('states in getStaticProps : ', data);

    return { props: { data: JSON.parse(JSON.stringify(data)) } };
};  

const Ninjas = ({ data: { states } }) => {
    console.log('Ninjas : ', states);
    return (
        <>
            <Head>
                <title> Listing</title>
            </Head>
            <div>
                {states.map((ei) => (
                    <div key={ei.state_id}>
                        <a className={styles.single}>
                            <h3>{ei.state_name}</h3>
                        </a>
                    </div>
                ))}
            </div>
        </>
    );
};

export default Ninjas;

以下是vercel日志。

20:17:40.644    Cloning github.com/user-name/co2-app (Branch: main, Commit: 8ab0e48)
20:17:41.349    Cloning completed: 704.592ms
20:17:41.374    Analyzing source code...
20:17:42.573    Installing build runtime...
20:17:45.235    Build runtime installed: 2.662s
20:17:48.104    Looking up build cache...
20:17:48.453    Build cache not found
20:17:49.697    Installing dependencies...
20:18:04.559    > ejs@2.7.4 postinstall /vercel/path0/node_modules/ejs
20:18:04.559    > node ./postinstall.js
20:18:05.113    npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.3.2 (node_modules/fsevents):
20:18:05.113    npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.3.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
20:18:05.116    added 600 packages from 352 contributors in 14.87s
20:18:05.426    64 packages are looking for funding
20:18:05.426      run `npm fund` for details
20:18:05.492    Detected Next.js version: 10.2.0
20:18:05.492    Running "npm run build"
20:18:05.756    > we2-cowax@0.1.0 build /vercel/path0
20:18:05.757    > next build
20:18:07.292    info  - Using webpack 4. Reason: custom webpack configuration in next.config.js https://nextjs.org/docs/messages/webpack5
20:18:08.224    info  - Checking validity of types...
20:18:08.244    Attention: Next.js now collects completely anonymous telemetry regarding usage.
20:18:08.245    This information is used to shape Next.js' roadmap and prioritize features.
20:18:08.245    You can learn more, including how to opt-out if you'd not like to participate in this anonymous program, by visiting the following URL:
20:18:08.245    https://nextjs.org/telemetry
20:18:08.326    info  - Creating an optimized production build...
20:18:08.748    > [PWA] Compile client (static)
20:18:08.748    > [PWA] Auto register service worker with: /vercel/path0/node_modules/next-pwa/register.js
20:18:08.750    > [PWA] Service worker: /vercel/path0/public/service-worker.js
20:18:08.750    > [PWA]   url: /service-worker.js
20:18:08.750    > [PWA]   scope: /
20:18:08.860    > [PWA] Compile server
20:18:25.603    info  - Compiled successfully
20:18:25.604    info  - Collecting page data...
20:18:26.366    info  - Generating static pages (0/3)
20:18:26.918    error :  invalid json response body at https://cdn-api.co-vin.in/api/v2/admin/location/states reason: Unexpected token < in JSON at position 0
20:18:26.919    Error occurred prerendering page "/". Read more: https://nextjs.org/docs/messages/prerender-error
20:18:26.919    Error: Error serializing props returned from `getStaticProps` in "/".
20:18:26.919    Reason: Props must be returned as a plain object from getStaticProps: `{ props: { ... } }`.
20:18:26.919        at isSerializableProps (/vercel/path0/node_modules/next/dist/lib/is-serializable-props.js:1:462)
20:18:26.919        at renderToHTML (/vercel/path0/node_modules/next/dist/next-server/server/render.js:30:1730)
20:18:26.919        at processTicksAndRejections (internal/process/task_queues.js:93:5)
20:18:26.919        at async /vercel/path0/node_modules/next/dist/export/worker.js:26:6
20:18:26.919        at async Span.traceAsyncFn (/vercel/path0/node_modules/next/dist/telemetry/trace/trace.js:6:584)
20:18:26.920    info  - Generating static pages (3/3)
20:18:26.921    > Build error occurred
20:18:26.926    Error: Export encountered errors on following paths:
20:18:26.926        /
20:18:26.926        at /vercel/path0/node_modules/next/dist/export/index.js:31:1106
20:18:26.926        at async Span.traceAsyncFn (/vercel/path0/node_modules/next/dist/telemetry/trace/trace.js:6:584)
20:18:26.927        at async /vercel/path0/node_modules/next/dist/build/index.js:43:49
20:18:26.927        at async Span.traceAsyncFn (/vercel/path0/node_modules/next/dist/telemetry/trace/trace.js:6:584)
20:18:26.927        at async /vercel/path0/node_modules/next/dist/build/index.js:25:1475
20:18:26.927        at async Span.traceAsyncFn (/vercel/path0/node_modules/next/dist/telemetry/trace/trace.js:6:584)
20:18:26.954    npm ERR! code ELIFECYCLE
20:18:26.954    npm ERR! errno 1
20:18:26.958    npm ERR! co2-app@0.1.0 build: `next build`
20:18:26.958    npm ERR! Exit status 1
20:18:26.958    npm ERR! 
20:18:26.959    npm ERR! Failed at the we2-cowax@0.1.0 build script.
20:18:26.959    npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
20:18:26.968    npm ERR! A complete log of this run can be found in:
20:18:26.968    npm ERR!     /vercel/.npm/_logs/2021-05-17T14_48_26_959Z-debug.log
20:18:26.982    Error: Command "npm run build" exited with 1

我使用 next-pwa 来实现 PWA 功能,因此使用自定义 webpack 版本

已在 Vercel 删除应用程序并重新部署,甚至删除了缓存构建但仍然无法解决错误

1 个答案:

答案 0 :(得分:1)

问题

API 返回 403 禁止错误:

!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML>

<HEAD>
    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
    <TITLE>ERROR: The request could not be satisfied</TITLE>
</HEAD>

<BODY>
    <H1>403 ERROR</H1>
    <H2>The request could not be satisfied.</H2>
    <HR noshade size="1px">
    Request blocked.
    We can't connect to the server for this app or website at this time. There might be too much traffic or a
    configuration error. Try again later, or contact the app or website owner.
    <BR clear="all">
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.
    <BR clear="all">
    <HR noshade size="1px">
    <PRE>
Generated by cloudfront (CloudFront)
Request ID: BqNxi8x1nTA3YKM_N3JSCyjGVDYnMUDNFvS_HgJGB8glTFr1uVh6Ug==
</PRE>
    <ADDRESS>
    </ADDRESS>
</BODY>

</HTML>

然后没有被您的 getStaticProps 函数正确处理(在这种情况下,无效响应不能转换为 JSON;此外,您的用户代理无效):

export const getStaticProps = async () => {
    const resp = await fetch(
        'https://cdn-api.co-vin.in/api/v2/admin/location/states',
        {
            headers: {
                'User-Agent': '*',
            }, //this is required by api provider
        }
    );

    // this throws an error because you can't turn
    // the invalid server response into JSON
    const data = await resp.json();

    return { props: { data: JSON.parse(JSON.stringify(data)) } };
};

您的 Ninjas 组件也没有正确处理 -- states 将是 undefined,因为服务器没有响应有效数据,您不能映射未定义的变量。相反,您应该通过使用 lodash 的 isEmpty: !isEmpty(states) && states.map(...) 或通过检查它是否已定义并具有长度:Array.isArray(states) && states.length > 0 && states.map(...) 来在映射之前检查状态是否为非空数组。

解决方案

import Head from "next/head";
import isEmpty from "lodash.isempty";

export const getStaticProps = async () => {
  let data = [];
  let error = "";
  try {
    const res = await fetch(
      "https://cdn-api.co-vin.in/api/v2/admin/location/states",
      {
        method: "GET",
        headers: {
          // update with your user-agent
          "User-Agent":
            "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36",
          Accept: "application/json; charset=UTF-8",
        },
      }
    );

    if (res.status !== 200)
      throw String(`Invalid server response: ${res.status} ${res.statusText}`);

    data = await res.json();

    if (isEmpty(data)) throw String("No data was found!");

    data = JSON.parse(JSON.stringify(data));
  } catch (e) {
    error = e.toString();
  }

  return {
    props: {
      data,
      error,
    },
  };
};

const Ninjas = ({ data, error }) => (
  <>
    <Head>
      <title> Listing</title>
    </Head>
    <div>
      {error && <p style={{ color: "red" }}>{error}</p>}
      {!isEmpty(data) && !isEmpty(data.states) &&
        data.states.map((ei) => (
          <div key={ei.state_id}>
            <a className={styles.single}>
              <h3>{ei.state_name}</h3>
            </a>
          </div>
        ))}
    </div>
  </>
);

export default Ninjas;