首页 > 解决方案 > Node/Express/Formidable 多部分表单 - 服务器上的请求正文*不存在*

问题描述

我是 Node/Express 的新手(但不是开发新手)。一切都很顺利——但我遇到了一个真正的障碍。

我正在尝试为“SPA”HTML 游戏建立一个框架。

我正在尝试发布 multipart/form-data - 因为最终我会想要上传文件。

我正在为 POSTS 使用 Fetch 和 FormData 对象——因为我想将 HTML 片段/JSON 'Ajax' 到我的 SPA 中

我的 POST看起来不错(对我来说)客户端 - 发布数据标题/有效负载/客户端

有一个多部分的有效载荷

但请求正文完全不存在服务器端(这(可能)导致 Formidable 返回一组空的字段)

没有请求.body

 const form = formidable({ multiples: true });

let outFields={}
form.parse(cmd.request,(err,fields,files)=>{outFields=fields})

我发誓 - 请求有一个 body 属性,但它是一个空对象{} 也不是很有用

我尝试过的事情: -

对 CORS 很感兴趣

//CORS - without this we cannot accept multipart forms (or do several other things later - this really wants locking down before production)
app.use((req, res, next:Function) => {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  res.setHeader('Access-Control-Allow-Methods', 'POST, GET'); // Add other methods here
  next();
});

放入、取出、取出(并动摇)中间件:--

app.use(logger('dev'));
//app.use(express.json());
//app.use(bodyParser.urlencoded({extended:true}))
//app.use(bodyParser.json())

(也许是空的身体进来的地方)

“已资助”并在https://www.npmjs.com/package/formidable寻求付费支持 (尚未回复)

弄乱了表单(添加了 enctype 和方法属性) - 无济于事

拉了很多我自己的头发

所以归结为:-

这是我的表格:-

<form id='signIn' method="post" enctype="multipart/form-data">
      <p>Enter your player name <input type='text' name='pName'></p>
      <p>Enter your password <input type='password' name='password'></p>
    </form>
    
    <!--(method, url,elementId,mode,formDataObj){ -->
    <button onclick="ajax('POST','signIn','main','i',new FormData($('#signIn')[0]))">Sign In</button>
    </form>

这是 ajax 辅助方法(还不是很漂亮 - 抱歉):-

//Fetch is the modern, native way - it is well described here https://javascript.info/fetch
  function ajax(method, url,elementId,mode,formDataObj){
    //we return a promise so we can await (completion if we want to)        
    return new Promise((resolve,reject)=>{resolve(fetch(url, {method:method,body:formDataObj,headers:{'Accept':'text/html','Content-Type':'multipart/form-data'}}).then(response=>fillElement(elementId,response,mode)))}) //response is a promise 
  }

和(不是很相关)-这是路由器/“控制器”代码

router.get('/*', (req:e.Request, res:e.Response, next:e.NextFunction)=> {processRequest(req,res,next)}) //res.render("main",{player:} }) //

function processRequest(req:e.Request,res:e.Response,next:e.NextFunction){
  
  //siginIn,signUp,signOut


  const action=req.path.split('/')[1]  //we're going to see if the controller object has a function matching the (first segment of) the path - NB: path[0] is what before the first slash (i.e. - nothing)
     
  if(controller.hasOwnProperty(action)){  //see if the controller object has a function matching the (first segment of) the path 
    const game:Game=global["game"] //get a type safe reference to the game
    let player:Player = game.playerFromCookie(req.cookies.pid)
    
    console.log (req.path)

    //construct a parameters object to pass useful info into the controller[action] method
    //export interface Params {readonly game:Game,readonly player:Player,request:e.Request,response:e.Response}
    let params:controller.Params = {game:game, player:player, request:req , response:res}
    //Invoke the method (action) with tha handy parameters
    let output:{template:string,data:any} = controller[action](params)

    res.render(output.template, {player:output.data}) 

在此先感谢您的时间

标签: node.jsexpressfetchmultipartform-dataformidable

解决方案


您的表单有 2 个 </form>,这会产生 2 个表单。

let outFields={}
form.parse(cmd.request,(err,fields,files)=>{outFields=fields})

不会做它看起来的样子。我建议您更多地了解回调一般是如何工作的,当您这样做时,就会很明显为什么这段代码是草率的。

而且您的 ajax 代码还表明您对 Promise 毫无头绪,因此请阅读文档和 gl hf


推荐阅读