在 Nextjs 中未发送响应即可解析 API

Posted

技术标签:

【中文标题】在 Nextjs 中未发送响应即可解析 API【英文标题】:API resolved without sending a response in Nextjs 【发布时间】:2020-06-26 06:46:06 【问题描述】:

我必须在我的 nextjs 项目中进行相同的更改,因为我的 enpoint API 不支持很多调用,我想每 3 分钟从原始数据中刷新一次。

我从 nextjs 实现了 API:我创建了一个 pages/api/data 并在内部调用我的端点,并在我的getInitialProps 内部索引调用数据文件。

get 工作正常,但我有 2 个问题:

1:我收到一条警告消息:

在未发送 /api/data 响应的情况下解析 API,这可能会导致请求停止。

2: 3 分钟后不会重新加载数据。我想这是因为 Cache-Control 值...

这是我的代码:

页面/api/数据

import  getData  from "../../helper";

export default async function(req, res) 
  getData()
    .then(response => 
      res.statusCode = 200
      res.setHeader('Content-Type', 'application/json');
      res.setHeader('Cache-Control', 'max-age=180000');
      res.end(JSON.stringify(response))
    )
    .catch(error => 
      res.json(error);
      next();
    );
;

页面/索引

import React,  useState, useEffect  from "react";
import fetch from 'isomorphic-unfetch'

const Index = props => 

  return (
    <>Hello World</>
  );
;

 Index.getInitialProps = async ( res ) => 
  const response = await fetch('http://localhost:3000/api/data')
  const users = await response.json()
  return  users 
;

export default Index;

【问题讨论】:

你试过等待 getData() 吗? 嗨,Alessio,我尝试等待,警报消息消失了!但数据现在返回 4 次... 【参考方案1】:

You should return a Promise and resolve/reject it.

例子:

import  getData  from "../../helper";

export default async function(req, res) 
  return new Promise((resolve, reject) => 
    getData()
      .then(response => 
        res.statusCode = 200
        res.setHeader('Content-Type', 'application/json');
        res.setHeader('Cache-Control', 'max-age=180000');
        res.end(JSON.stringify(response));
        resolve();
      )
      .catch(error => 
        res.json(error);
        res.status(405).end();
        resolve(); // in case something goes wrong in the catch block (as vijay commented)
      );
  );
;

【讨论】:

如果出现错误,答案中的代码可能会抛出 UnhandledPromiseRejectionWarning。在 catch 块中你应该这样做: res.status(405).end();返回解析() 从异步函数返回一个承诺是多余的。最好在getData 上使用await,放弃所有嵌套,并返回您喜欢的任何值,而不是resolveing。 我完全同意在 async 函数中返回显式 Promise 并不总是必要的。但在我看来,如果我们使用await,则返回没有任何用处。这里的问题是 NextJS 只想要该函数的一些返回值,不管它是什么。返回 data.someValue 之类的内容可能会让人感到困惑。 我遇到了同样的错误。我忘了在我的 api 默认函数中的异步函数前面添加 await【参考方案2】:
import  getData  from "../../helper";

export default async function (req, res) 
  try 
    const response = await getData();
    res.statusCode = 200;
    res.setHeader('Content-Type', 'application/json');
    res.setHeader('Cache-Control', 'max-age=180000');
    res.end(JSON.stringify(response));
  

  catch (error) 
    res.json(error);
    res.status(405).end();
  

【讨论】:

【参考方案3】:

您可以使用 'next-connect' 库,它消除了在这种情况下返回承诺的必要性。如果你喜欢express.jsroute-&gt;middleware-&gt;endpoint 模式,这个库就是你要找的。它还提供开箱即用的全局错误处理! [next-connect docs]

例子:

import nc from 'next-connect'

function onError(err, req, res, next) 
  logger.log(err);

  res.status(500).end(err.toString());
  // OR: you may want to continue
  next();


const handler = nc( onError );

handler
  .use((req, res, next) => 
    if(!req.user)
      throw new Error("oh no!");
      // or use next
      next(Error("oh no"));
    
  )
  .get((req, res) => 
    res.end("success")
  )

【讨论】:

以上是关于在 Nextjs 中未发送响应即可解析 API的主要内容,如果未能解决你的问题,请参考以下文章

NEXTJS 将表单数据发送到 api 端点 - 无响应

即使在发送响应时也能在不发送响应错误的情况下解析 API

json 响应中的特殊字符在 IE 中未解析

AppCompatActivity 中未解析的 Android Activity Results API 引用

以(Json 格式)解析来自 Google Place api 响应的数据

Next JS api 路由类型为 graphql 错误(解析器不是函数)