【问题标题】:Query string variables still empty in Express 4Express 4 中的查询字符串变量仍然为空
【发布时间】:2017-08-28 22:20:55
【问题描述】:

按照stackoverflow 上的建议编写简单服务器:

rest_api.js:

const express = require('express');
const bodyParser = require('body-parser')

// Initialize RESTful server
const app = express();

app.set('port', (process.env.PORT || 5000));
app.use(bodyParser.json() );                        // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({extended: true}));   // to support URL-encoded bodies

// Spin up the server
app.listen(app.get('port'), function() {
    console.log('running on port', app.get('port'))
});

app.post('/bookinghandler', function (req, res) {
    let senderId = req.query.sender;
    let email = req.query.email;
    let hotelName = req.query.hotelName;
    let confirmNumber = req.query.confirmNumber;
    let start = req.query.startDate;
    let end = req.query.endDate;
}

app.js:

// This loads the environment variables from the .env file
require('dotenv-extended').load();

const builder = require('botbuilder');
const restify = require('restify');

// Setup Restify Server
var server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, function () {
   console.log('%s listening to %s', server.name, server.url); 
});

// Create chat connector for communicating with the Bot Framework Service
var connector = new builder.ChatConnector({
    appId: process.env.MICROSOFT_APP_ID,
    appPassword: process.env.MICROSOFT_APP_PASSWORD
});

// Listen for messages from users 
server.post('/api/messages', connector.listen());

var bot = require("./bot")
bot.InitializeBot(connector);

// Load REST API module
var restApi = require("./rest_api");

并且想通过查询字符串获取参数(URL中的示例请求:bookinghandler?sender=100000250242810&email=some@email.com&hotelName=Grand Hotel&confirmNumber=654321&startDate=2017-10-11&endDate=2017-10-15)。

但是req.paramsreq.param()req.bodyreq.query 仍然是空的。我做错了什么?这是通过require('url')require('qs') 完成的唯一方法吗?如果我只想通过快递?

【问题讨论】:

  • 嗯,通常如果您正在寻找查询参数,它应该是一个 GET 方法,不是吗? app.get(...)
  • @MarcoTalento,但 GET 可能对我也不起作用——一切都是空的。
  • 修改的时候记得重启服务器吗?
  • @Boaz 当然! :) 否则返回Cannot GET /bookinghandler

标签: node.js express query-string


【解决方案1】:

问题在于使用 2 个 REST 框架:express 和 restify。需要将整个应用程序作为 restify 或 express 应用程序。在我有一个 restify 服务器之前,在里面创建了另一个 express 服务器(只是举了不同的例子)。一般需要使用其中一种,不能同时使用。

修改后的 app.js:

// This loads the environment variables from the .env file
require('dotenv-extended').load();

const builder = require('botbuilder');
const restify = require('restify');

// Setup Restify Server
var server = restify.createServer();
server.use(require('restify-plugins').queryParser());
server.listen(process.env.port || process.env.PORT || 3978, function () {
   console.log('%s listening to %s', server.name, server.url); 
});

// Index route
server.get('/', function (req, res) {
    res.send('My chat bot')
});

// Create chat connector for communicating with the Bot Framework Service
var connector = new builder.ChatConnector({
    appId: process.env.MICROSOFT_APP_ID,
    appPassword: process.env.MICROSOFT_APP_PASSWORD
});

// Listen for messages from users 
server.post('/api/messages', connector.listen());

var bot = require("./bot")
bot.InitializeBot(connector);

// Load REST API module
var restApi = require("./rest_api");

// POST request from webview page
server.post('/bookinghandler', restApi.BookingHandler);

修改过的 rest_api.js:

const service = require("./service");

module.exports.BookingHandler = async function (req, res, next) {
    let senderId = req.query.sender;
    let email = req.query.email;
    let hotelName = req.query.hotelName;
    let confirmNumber = req.query.confirmNumber;
    let start = req.query.startDate;
    let end = req.query.endDate;

    res.send(200);  // Success
    return next(false);
};

【讨论】:

    【解决方案2】:
    app.post('/bookinghandler', function (req, res) {
           let senderId = req.query.sender;
           let email = req.query.email;
           let hotelName = req.query.hotelName;
           console.log(req.query, senderId, email, hotelName)
    })
    

    在我的终端打印这个输出

    { sender: '100000250242810', email: 'some@email.com', hotelName: 'Grand' } '100000250242810' 'some@email.com' 'Grand'

    【讨论】:

    • 使用高级 REST 客户端甚至通过浏览器发送请求。所有变量和查询对我来说都是未定义的 - console.log(req.query, senderId, email, hotelName) 输出:[Function: getQuery] undefined undefined undefined
    • 主要问题为什么它对你有用,对我不起作用?!会不会和resitfy有冲突?我也从app.js 调用此代码,如下所示:var restApi = require("./rest_api");
    • 能否请您发布您为会话设置 cookie 的位置的代码?
    • 它不是一个网络应用——服务器应用、后端、无 cookie、无会话等。
    • 你真的应该让整个应用程序成为一个 express 应用程序,现在你似乎有一个 restify 服务器,并且在里面你正在创建另一个 express 服务器。通常,您使用其中一种,而不是同时使用两种。
    【解决方案3】:

    每当使用查询发出请求时,查询必须存在于 服务器识别他们的url。

    这是给您的示例代码。您需要将查询添加到您的 html 表单中。您还可以使用& 将它们分开。

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title></title>
      </head>
      <body>
        <form action="/as/?sender=321&email=myemail@email.com" method="post">
          <input type="text" name="myName" value="">
          <input type="submit" name="" value="ssss">
        </form>
      </body>
    </html>
    

    这里是app.js

    app.post('/bookinghandler', function (req, res) {
    
        var senderId = req.query.sender;
        var email = req.query.email;
        console.log('senderId = ' + senderId + ' email = ' + email);
        res.end("got the info");
    });
    

    现在,你要问我这样做的目的,因为我们已经在 form 中定义了它们。好吧,真正的网站不会这样做。如果您想评估您的查询,您需要将它们留空并查看用户在浏览器上是否有任何 cookie。

    这是html表单

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title></title>
      </head>
      <body>
        <form action="/as/?sender=&email=" method="post">
          <input type="text" name="myName" value="">
          <input type="submit" name="" value="ssss">
        </form>
      </body>
    </html>
    

    这是我们的应用程序

    app.post('/bookinghandler', function (req, res) {
        if(req.session.user.id){  //checking the cookies if the user is logged in/exists
           var senderId = req.query.sender;
           var email = req.query.email;
        }else{
         res.send("you haven't logged in");
         return false;
        }
    
        console.log('senderId = ' + senderId + ' email = ' + email);
        res.end("got the info");
    });
    

    有关 cookies 的节点模块的更多信息,请参阅here

    结论

    表单上的查询大多是额外的工作,只需使用req.body 和cookie,req.session 对象就可以轻松完成这项工作。人们通常不会使用它,除非他们有额外的数据要在客户端和服务器之间传输。

    更新

    node.js 中的参数定义如下/:param

    如果你想使用参数

    app.get('/bookinghandler/:myParam/?queriesHere='){
       console.log(req.params.myParam + "   and the query: " + req.query.queriesHere);
    
    res.send(req.params.myParam + "   and the query: " + req.query.queriesHere);
    }
    

    添加此代码,然后复制并转到此 url localhost:5000/bookinghandler/hereisaparam/?queriesHere=123

    确保添加端口

    如果是服务器应用,创建另一个 node.js 文件,然后同时运行它们

    otherfile.js

    var request = require('request');
    request('http://localhost:5000/bookinghandler/hereisaparam/?queriesHere=123', function (error, response, body) {
      if(error){
    console.log(error):
    return false;
    }
      console.log('body:', body); // Print the data
    });
    

    在服务器运行时运行此文件。

    【讨论】:

    • 我不是从网站或其他任何地方发送查询:只是浏览器或高级 REST 客户端中的 URL。网址很简单:localhost:5000/bookinghandler?sender=100000250242810&amp;email=some@email.com&amp;hotelName=Grand%20Hotel&amp;confirmNumber=654321&amp;startDate=2017-10-11&amp;endDate=2017-10-15
    • req.url 正确:/bookinghandler?sender=100000250242810&amp;email=some@email.com&amp;hotelName=Grand%20Hotel&amp;confirmNumber=654321&amp;startDate=2017-10-11&amp;endDate=2017-10-15 但是参数仍未定义。
    • 那是因为你在那个 url @AlekseyKontsevich 中没有任何参数
    • 我不使用任何表单或页面,GET 效果不如我上面提到的。
    • 您是否尝试做一个简单的发布请求?
    猜你喜欢
    • 1970-01-01
    • 2023-03-18
    • 2017-07-20
    • 2013-01-18
    • 2021-06-23
    • 2017-04-13
    • 2019-01-28
    • 2011-04-19
    • 1970-01-01
    相关资源
    最近更新 更多