![](/img/trans.png)
[英]How to make a POST request to a nodejs RESTful API in reactjs
[英]NodeJS RESTful API - How to handle 'undefined' request variables properly?
我正在使用NodeJS和Express開發RESTful API。
我注意到傳入的請求有時缺少一些預期的變量,這會導致程序崩潰,並說它無法將變量的值設置為'undefined'
值-因為沒有值隨請求到達。
例:
該應用程序期望使用variableY,但是正在發送variableX:
formData: { variableX: 'valueX' }
該程序希望接收variableY,其代碼如下:
const checkVariables = Joi.validate({
variableY: req.body.variableY,
}, schema);
應用程序因以下錯誤而崩潰:
TypeError: Cannot read property 'variableY' of undefined
我考慮了幾種處理方法,包括在應用程序啟動時聲明變量,以及使用try-catch
一起使用它們。
另一種方法是使用if-else
, if-chaining
或case-switch
,但是正如您所理解的,我當然正在尋找實現這一目標的最簡潔的方法。
有任何想法嗎?
謝謝。
**編輯**
僅使用對象進行了開發並設法獲得了結果。 一旦嘗試到達其中的任何內部字段,該錯誤都將被拋出,例如:
if(req.body.variableY == undefined){console.log('The expected variable is undefined');} //true
驗證處理“未定義”對象內的字段時:
if(req.body.variableY.dataId == undefined){console.log('The expected variable is undefined');} //crashes
再次引發以下錯誤:
TypeError: Cannot read property 'variableX' of undefined
經過更多的挖掘之后,發現以下Stackoverflow線程:
如何使用保存屬性名稱的變量檢查對象屬性是否存在?
使用hasOwnProperty進行了嘗試,但引發了相同類型的錯誤:
TypeError: Cannot read property 'hasOwnProperty' of undefined
嘗試使用try-catch
包裝變量聲明,但仍然無法正常工作:
try{
var variableX = req.body.variableX
var variableXDataId = req.body.variableX.dataId
}
catch(e){
res.status(400).send('Wrong request error: Please check your request variables and try again');
}
由於這是大多數RESTful API都應解決的非常基本的驗證(驗證您是否在請求中獲得了預期的傳入變量,因此該程序不會因無法處理的錯誤而崩潰-常見的問題解決此類問題(預期/意外請求驗證)的解決方案?
謝謝。
你可以采取另一種方法,檢查req.body
你到達之前checkVariables
:
let body = req.body;
// data - your req.body
// requiredKeys - is an array of strings , [ key1, key2 ... keyN] | string[]
const setKeys = ( data, requiredKeys )=>{
if( !typeof requiredKeys.length ){
requiredKeys = [];
}
if(requiredKeys.length) requiredKeys.forEach( k =>{
k = k.replace(/\+/g,'/');
let keysList = [];
if( /\/+/g.test(k)){
keysList = k.split('/');
}else{
keysList = [k];
}
let [firstKey, ...rest] = keysList;
if( typeof data[firstKey] === 'undefined' ){
data[firstKey] = {};
}
if( rest.length ){
data[firstKey] = setKeys(data[firstKey], [rest.join('/')] );
}
})
return data;
}
let checkedData= setKeys(body, ['variableT','variableP/noname/emptyObj','custom/object/does/not/exist/but/it/will/be/created/here']);
const checkVariables = Joi.validate(checkedData, schema);
UPDATE
在下面,您將找到一個工作示例,說明在/
(假設/ usersStatus /:id)請求期間事情如何工作:
const express = require('express') const app = express() const port = 3000 const setKeys = (data, requiredKeys) => { if (!typeof requiredKeys.length) { requiredKeys = []; } if (requiredKeys.length) requiredKeys.forEach(k => { k = k.replace(/\\+/g, '/'); let keysList = []; if (/\\/+/g.test(k)) { keysList = k.split('/'); } else { keysList = [k]; } let [firstKey, ...rest] = keysList; if (typeof data[firstKey] === 'undefined') { data[firstKey] = {}; } if (rest.length) { data[firstKey] = setKeys(data[firstKey], [rest.join('/')]); } }) return data; } /** * Mock some data */ const getUserData = (req, res, next) => { if (typeof req.body === 'undefined') { req.body = {}; } req.body = { variableY: { someName: 23 }, variableZ: { name: 3, type: { id: 5, typeName: 'something', tags: ['a', 'b', 'c'] } } }; console.log('Middleware 1 getUserData'); next(); } /** * 1. Setup our middleware for checking keys * "requiredKeys" is an array of strings */ const middlewareSetKeys = (requiredKeys, wrappedMiddleware) => { return (req, res, next) => { console.log('Middleware 2 middlewareSetKeys'); if (typeof req.body === "undefined") { console.log('Leaving Middleware 2 since we don\\'t have req.body'); next(); } /** * Update "req.body" with keys that we want to have available * in our next middleware */ req.body = setKeys(req.body, requiredKeys); if (typeof wrappedMiddleware === 'function') { return wrappedMiddleware.call(this, req, res, next); } else { next(); } } } /** * 2. Let's assume a "user status" situation * 2.1. We need userInfo from database * 2.2. Some info won't be retrieved, unless the user accesed some parts of the website to trigger some mechanisms that allows those fields to be exposed, therefore the lack of keys * 2.3. But we know those keys/objects, and we still want to be present so our code won't crash. */ // lets call our getUserData app.get( '/', // this path is for some userInfo getUserData, // this returns userInfo and appends it to `req.data` middlewareSetKeys([ 'userActivity/daily/jobs', // these won't exist in getUserData because the user is lazy and he didn't apply for any JOBS 'userStatus/active/two-weeks-ago', // these won't exist in getUserData because the user joined two days ago. BUT WE STILL NEED IT coz reazons. ]), // We set our desired-later-to-use keys (req, res, next) => { /** * 3. Now our req.body will have our keys * even if they didn't exist in the getUserData middleware */ console.log('Middleware 3 Your middleware'); console.log(req.body); res.setHeader('Content-Type', 'application/json'); res.send(JSON.stringify(req.body, null, 2)) }) app.listen(port, () => console.log(`Example app listening on port ${port}!`))
您可以使用快遞驗證器https://www.npmjs.com/package/express-validator驗證傳入請求。然后將其添加到控制器中,其中a,b,c,d是您要驗證的參數
const nonEmptyFields = ['a', 'b', 'c', 'd']; nonEmptyFields.forEach(field => req.assert(field, `${field} cannot be blank`).notEmpty()); const errors = req.validationErrors(); if (errors) { return res.status(400).send(errors); }
用於驗證字段內的字段,您可以嘗試執行此操作
typeof(req.body && req.body.name !== undefined)
一個解決方案是設置一個默認的空對象,以替換父級的undefined:
// checking for body.variableX.variableZ with object destructuring ES6
const {body = {}} = request;
const {variableX = {}, variableY} = body;
const {variableZ} = variableX.variableZ;
// or prior ES6
var body = request.body || {};
var variableX = body.variableX || {};
var variableY = variableX.variableY;
// or in a statement
var variableY = request.body && request.body.variableX ? request.body.variableX.variableY : undefined;
基於此,您可以創建自己的函數,如getValue(request, 'body.variableX.variableY')
,如果未定義任何父項或最終值,則返回null:
// asumes the value in the path is either object or undefined
function getValue(rootObj, path = '') {
const parts = key.split('.');
let value = rootObj || {};
let part;
while ((part = parts.shift()) && value !== null) {
value = value[part] || null;
}
return value;
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.