Node/Express/Formidable 多部分表单 - 服务器上*不存在*请求正文

问题描述

我是 Node/Express 的新手(但不是开发人员)。一切进展顺利 - 但我遇到了真正的障碍。

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

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

我将 Fetch 和 FormData 对象用于 POSTS - 因为我想将“Ajax”HTML 片段/JSON 放入我的 SPA

我的 POST 看起来 ok(对我来说)客户端 - Post data headers/payload/client-side

具有多部分有效载荷

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

No request.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 和 method 属性)- 无济于事

  • 列表项

拔了很多自己的头发

  • 以公平的方式进入图书馆 - 但 TBH 这超出了我的专业范围

所以把它煮沸:-

这是我的表格:-

<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,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,next)}) //res.render("main",{player:} }) //

function processRequest(req:e.Request,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}) 

提前感谢您的时间

解决方法

您的表单有 2 个 </form>,可以生成 2 个表单。

还有

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

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

你的 ajax 代码也显示你对 Promise 一无所知,所以阅读文档和 gl hf

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...