问题描述
我是 Node/Express 的新手(但不是开发人员)。一切进展顺利 - 但我遇到了真正的障碍。
我正在尝试为“SPA”HTML 游戏建立一个框架。
我正在尝试 POST multipart/form-data - 因为最终我会想要上传文件。
我将 Fetch 和 FormData 对象用于 POSTS - 因为我想将“Ajax”HTML 片段/JSON 放入我的 SPA
我的 POST 看起来 ok(对我来说)客户端 - Post data headers/payload/client-side
具有多部分有效载荷
但请求正文完全不存在服务器端(这(大概)导致 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 和 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