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

Posted

技术标签:

【中文标题】即使在发送响应时也能在不发送响应错误的情况下解析 API【英文标题】:Getting API resolved without sending a response error even when sending response 【发布时间】:2021-12-04 22:13:07 【问题描述】:

我在成功将数据保存在数据库中并保存上传图像后尝试发送res.json,但我不断收到API resolved without sending a response for /api/auth/registeration, this may result in stalled requests.。我还在 Next.js 中使用了强大的图像上传。

代码:

import connection from "../../../utils/connection/getConnection";
import formidable from "formidable";
const signupSchema = require("../../../models/signup");
import mkdirp from "mkdirp";
import bcrpt,  genSaltSync  from "bcrypt";
import fs from "fs";
export const config = 
  api: 
    bodyParser: false,
  ,
;

const handlePost = async (req, res) => 
  const form = formidable.IncomingForm();

  form.parse(req, async function (err, field, files) 
    await fileSavour(field, files);
    return res.json(
      message: "success",
    );
  );
;

const fileSavour = async (fields, files) => 
  let  email, password  = fields;
  let imageName = files.image.name;

  let newPassword = await bcrpt.hash(password, genSaltSync(10));

  const newUser = new signupSchema(
    email,
    password: newPassword,
    image: imageName,
  );

  const Nuser = await newUser.save();

  if (Nuser) 
    await mkdirp("public/profileImages/" + Nuser._id);

    if (imageName) 
      const data = fs.readFileSync(files.image.path);

      const pathToSave = "public/profileImages/" + Nuser._id + "/" + imageName;

      fs.writeFileSync(pathToSave, data);
      await fs.unlinkSync(files.image.path);
      return;
    
  
;

const Register = async (req, res) => 
  req.method === "POST"
    ? handlePost(req, res)
    : req.method === "PUT"
    ? console.log("PUT")
    : req.method === "DELETE"
    ? console.log("DELETE")
    : req.method === "GET"
    ? console.log("GET")
    : res.status(404).send("");
;

export default Register;

【问题讨论】:

【参考方案1】:

您需要承诺form.parse 功能。目前,您的请求在表单被解析之前被返回。

让我们定义一个使用formidable 承诺表单解析的函数,并用它来解析所有请求。函数应该是这样的 -

const promisifiedParseForm = (req) => 
   const form = formidable.IncomingForm();
   return new Promise((resolve, reject) => 
      form.parse(req, function (err, field, files) 
         if (err) 
            reject(err)
          else 
            resolve( field, files )
         
      );
   );

handlePost函数中使用promisifiedParseForm函数,像这样-

const handlePost = async (req, res) => 
   const  field, files  = await promisifiedParseForm(req);
   
   await fileSavour(field, files);

   return res.json(
      message: "success",
   );
;

【讨论】:

【参考方案2】:

handlePost 处理函数不会等待form.parse 回调执行(以及随后调用res.json),而是立即返回。为了防止这种情况,您可以用 Promise 包装 form.parse 以确保处理程序等待回调函数执行。

const handlePost = async (req, res) => 
    const form = formidable.IncomingForm();
    
    await new Promise(function(resolve, reject) 
        form.parse(req, async function(err, fields, files) 
            await fileSavour(field, files);
            resolve();
        );
    );

    res.json( message: "success" );
;

【讨论】:

以上是关于即使在发送响应时也能在不发送响应错误的情况下解析 API的主要内容,如果未能解决你的问题,请参考以下文章

你能在接收者不可见的情况下发送数据包吗?

Fiddler--AutoResponder

Fiddler--AutoResponder

即使在发送 CORS 标头后从浏览器发送请求到播放服务器时也出现 CORS 错误

如何在不等待结果的情况下将 SQL 查询发送到 PHP 中的数据库

减少 KafkaProducer 发送异步响应时间