formidable上传,第一张上传成功,再上传错误Can\'t set headers after

用nodejs的formidable上传图片,第一张上传成功,再上传发生错误Can't set headers after they are sent

  • 1 错误表现

https://img3.mukewang.com/5c7f39e400016b9308000358.jpg

图上的结果是:我在mavoneditor编辑器里面上传第一张图片时,可以正确从服务端返回图片的网络地址,再上传第二张图片的时候,就报错了,图片地址任然是本地地址。

  • 2 服务端的报错

https://img.mukewang.com/5c7f39f40001eaa208000312.jpg

从信息上也看出我第一次post /upload 是成功的,前端也正确get 到了服务端图片地址,第二次post却发生错误了,错误信息 Can't set headers after they are sent

但第二次上传的图片却已经上传到了服务端

https://img3.mukewang.com/5c7f3a0d00015b5904320105.jpg

虽然从图上看不出来,但upload里面的确多了一张图片

  • 3 代码

上传图片的前端代码

https://img1.mukewang.com/5c7f3a1b00011b9f08630640.jpg

服务端代码

https://img.mukewang.com/5c7f3a300001330d06840941.jpg

查了好多资料,大概知道这个错误是因为 我在发了一次http响应头之后又发了一次响应头,程序做出了重复响应,但我检查了半天也没发现哪里重复谢了多个res.xxx啊,其它写return的办法也试过,还是没解决。

同时前端会有一个跨域代理的错误

[HPM] Error occurred while trying to proxy request //upload from localhost:8080 to http://localhost:8088 (ECONNRESET) (https://nodejs.org/api/errors...
_common_system_errors)

为了测试是否与跨域代理有关系,我将项目打包放到服务端测试,发现还是一样的错误,再次求助各位帮忙看看解决,先谢过了!!


沧海一幻觉
浏览 432回答 1
1回答

陪伴而非守候

首先,解决问题遇到类似问题,官方文档往往是最好的解答。试下把你的代码改成下面这样,唯一的不同,就是把form的实例化挪动动 upload 里。  // 上传图片  upload: (req, res, next) => {    const form = new formidable.IncomingForm() // 注意,把form 的实例化操作挪进来    //上传文件的保存路径    form.uploadDir = path.dirname('./upload/upload/')    //保存扩展名    form.keepExtensions = true    //上传文件的最大大小    form.maxFieldsSize = 20 * 1024 * 1024    form.parse(req, (err, fields, files) => {            // 项目未打包时使用      const imagepath = 'http://localhost:8088/' + path.normalize(files.file.path)      // 项目打包到server之后使用      // const imagepath = path.normalize(files.file.path)      res.status(200).send(imagepath)      // return next()    })      },官方文档在 这里,仔细看两眼就会发现你的代码跟它的差别。其次,探究问题根源如果好奇问题出在哪里,可以看下 formidable 的源码,incoming_form.js。因为你所有的parse操作都是在同一个form实例上进行,因此,this.on('end') 会被调用多次。第一次上传:注册'end'回调,假设回调为 cb1。文件上传成功,cb1调用第二次上传:新增'end'回调,假设回调为 cb2。由于 this.on() 注册是累加的,当前end事件的回调有两个,cb1、cb2。文件上传成功,cb1首先被调用,然后就悲剧了IncomingForm.prototype.parse = function(req, cb) {  // 忽略一堆无关紧要的代码....  // 注册各种回调,同样忽略掉无关紧要的代码  if (cb) {      this.on('end', function() {        cb(null, fields, files);      });  }
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript