【问题标题】:Node.js, Express Calling function twice, One with complete req.body, One with an empty bodyNode.js,两次快速调用函数,一次完整的req.body,一次空体
【发布时间】:2015-10-29 22:55:35
【问题描述】:

所以这将很难解释,我尽力而为。 我有一个 iOS 应用程序和 android 在他们的 web 视图中点击相同的 node.js 应用程序。 iOS Web 视图可以很好地打开 node.js 应用程序。然而,安卓遇到了麻烦。我已经将它追踪到一个被命中的路由函数:

 app.post('/', auth.processDeviceLogin);

在我的身份验证页面上:

exports.processDeviceLogin = function(req, res){
var param;

if(typeof req.body.metaData !== 'undefined'){
    param = req.body;
}
else {
    //Android will hit this condition as items are not posted with application/json content type.
   param = JSON.parse(Object.keys(req.body));

}

auth.makeDeviceLoginRequestQ(
    stuff
).then(function(_data) {
        return moreStuff;
    })
    .then(function(_user){
        return againMoreStuff;
    })
    .spread(function(_user, token){
        //blah blah blah

        res.render('device', obj);
    })
    .catch(function(error){
        res.json({status:"fail", reason:error});
    })
    .done();
};

这是我遇到的情况:当我调试代码并逐步执行时,我正确收到了第一个请求。所有标题/正文/等都是从应用程序接收的。然而,突然之间,这个函数再次被调用并且请求信息大部分是空的。正文为空,一些标头信息在那里,但内容类型为空。它抛出

SyntaxError:输入意外结束 在 Object.parse (本机) 在exports.processDeviceLogin 行

  param = JSON.parse(Object.keys(req.body)) 

这个错误提示一个简单的语法错误,但我已经调试了很多。我什至硬编码了从 iOS 版本获得的相同参数值,但无济于事。我猜这与从某个地方进来的第二个空请求有关。

这个函数被命中两次,被调用者是(Express路由器包的一部分):

Layer.prototype.handle_request = function handle(req, res, next) {
  var fn = this.handle;
  if (fn.length > 3) {
    // not a standard request handler
    return next();
}

 try {
    fn(req, res, next);
   } catch (err) {
   next(err);
   }
 };

我想我的问题是,什么会导致使用空 request(req) 值再次调用此函数?我完全迷路了。任何帮助都会很棒。 非常感谢

【问题讨论】:

    标签: javascript android node.js express


    【解决方案1】:

    这个JSON.parse(Object.keys(req.body)); 对我没有任何意义。

    如果req.body 是一个JSON 字符串,那么在它上面调用Object.keys() 是没有意义的,因为在一个普通的JS 字符串上Object.keys() 不会给你任何有用的东西。

    如果req.body已经是一个JS对象,那么就不需要解析了。而且,您永远不要在Object.keys() 的输出上调用JSON.parse(),因为这是将一个JS 数组传递给JSON.parse()

    这段代码看起来不对。 JSON.parse() 应该传递一个 JSON 字符串。

    你可以这样做:

    if (typeof req.body === "string") {
        // if JSON string, then parse it
        param = JSON.parse(req.body);
    } else if (typeof req.body === "object") {
        // if already parsed into an object, then get the keys
        param = Object.keys(req.body);
    } else {
        // some sort of error handling here for unexpected data 
    }
    

    【讨论】:

    • 上述原因是因为我从Android端得到的req body看起来像这样,之前和解析等等:
    • { '{"actionInfo":{"type":"something"},"metaData":{"action":"GET","apiVersion":"2","appId": “某事”,“appVersion”:“2.5.7”,“appVersionCode”:某事,“语言”:“en_US”,“纬度”:某事,“经度”:某事,“osVersion”:“Android API 23”, "uniqueDeviceId":"something","brandTo":"something","model":"unknown Android SDK built for x86_64 (generic_x86_64)","device":"Android 6.0"},"userData":{"sessionId" :"something","authority":"ALL","userId":"something","type":"USER","anotherId":"something"}}': '' }
    【解决方案2】:

    嗯,这很愚蠢。问题与我使用的 Android 模拟器版本有关。 Marshmallow 根本不适用于这个 web view url post。而 Api 21 工作得很好。仅供参考,如果这是您的问题,请测试不同的模拟器类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-15
      • 2011-09-16
      • 2019-11-07
      • 2017-04-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多