node.js - Node/Express/Formidable 多部分表单 - 服务器上的请求正文*不存在*
问题描述
我是 Node/Express 的新手(但不是开发新手)。一切都很顺利——但我遇到了一个真正的障碍。
我正在尝试为“SPA”HTML 游戏建立一个框架。
我正在尝试发布 multipart/form-data - 因为最终我会想要上传文件。
我正在为 POSTS 使用 Fetch 和 FormData 对象——因为我想将 HTML 片段/JSON 'Ajax' 到我的 SPA 中
我的 POST看起来不错(对我来说)客户端 - 发布数据标题/有效负载/客户端
有一个多部分的有效载荷
但请求正文完全不存在服务器端(这(可能)导致 Formidable 返回一组空的字段)
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 和方法属性) - 无济于事
- 项目清单
拉了很多我自己的头发
- 踏入图书馆的公平之路-但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, 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})
在此先感谢您的时间
解决方案
您的表单有 2 个 </form>
,这会产生 2 个表单。
还
let outFields={}
form.parse(cmd.request,(err,fields,files)=>{outFields=fields})
不会做它看起来的样子。我建议您更多地了解回调一般是如何工作的,当您这样做时,就会很明显为什么这段代码是草率的。
而且您的 ajax 代码还表明您对 Promise 毫无头绪,因此请阅读文档和 gl hf
推荐阅读
- c++ - C++ 服务器响应在客户端页面 WebSocket Winsock Windows VS 上显示标题信息
- sql - 如何在 SQL Server 中将行显示为相同 ID 的列?
- javascript - 尝试在同一类的函数中调用其他函数。未捕获的 TypeError:this.saveToHist 不是 HTMLCanvasElement 的函数
- reactjs - 如何将我的网络应用程序中的图像分享到 Instagram?
- android - 将 Google Play Developer API 限制为单个应用程序,并且仅限 alphas/betas
- powershell - 使用 PowerShell 使用升级代码查找产品版本
- python - 如何解决使用 Python 进行渲染的属性错误?
- ruby - 在 Ruby 中用 \' 替换
- python - Python if line = string,从文件中打印下一行
- sas - SAS 打印到自定义报告