Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Node.JS在询问实际存在的端点时返回404_Javascript_Angularjs_Node.js - Fatal编程技术网

Javascript Node.JS在询问实际存在的端点时返回404

Javascript Node.JS在询问实际存在的端点时返回404,javascript,angularjs,node.js,Javascript,Angularjs,Node.js,我有一个web应用程序,由以前的一家公司启动,用Angular.JS编写应用程序向后端公开一个请求(用Node.JS+Express编写),以收集填充表所需的一些数据具体来说,这是每次用户进入保存表的页面时应用程序发送的请求(config变量保存访问令牌) handleSuccess和handleError就是这样定义的 handleSuccess: function (res) { debugger; var deferred =

我有一个web应用程序,由以前的一家公司启动,用Angular.JS编写
应用程序向后端公开一个请求(用Node.JS+Express编写),以收集填充表所需的一些数据
具体来说,这是每次用户进入保存表的页面时应用程序发送的请求(config变量保存访问令牌)

handleSuccess和handleError就是这样定义的

        handleSuccess: function (res) {
            debugger;
            var deferred = $q.defer();
            res.data.success ? deferred.resolve(res.data) : deferred.reject(res.data.message);
            return deferred.promise;
        },

        handleError: function (error) {
            return {
                success: false,
                message: error
            };
        }
在我的后端中,我为任何使用“/api”前缀调用的对象设置了一个侦听器,如下所示

app.use('/api', authorization.validateToken);
和另一个侦听器,只有在没有匹配的情况下才可以工作(写在处理应用程序所有常规查询的文件末尾)

最后,这是应该从Angular.js在后端调用的端点

app.get('/api/myPath/for/Having/Data', something.somethingToCall);
有趣的是:出于一个我仍然需要理解的原因,Angular.JS两次调用该端点,导致一个过程失败(404),另一个过程进展顺利(200)。
操作流程应该是这样的:如果一切正常,后端-->节点将检查令牌-->执行操作的有效性。
该操作会被调用两次(这要感谢Visual Studio代码调试器和Chrome的网络监视器),并且,即使每次都正确执行令牌的验证过程,下一次()函数将第一次保存app.all()侦听器。
此外,甚至在我开始调试发送的第一个请求之前,Google Chrome上的JavaScript控制台就警告我出现了一个错误,比如“无法读取未定义的属性‘数据’”,这意味着请求执行两次,第一次返回404

exports.validateToken = (req, res, next) => {
    console.log(`check user here`);
    // next();
    var token =  //I take the token 
    console.log(token);
    if (token) {
        jwt.verify(token, require('../../secret'), (err, decoded) => {
            if (err) {
                res.send({
                    success: false,
                    status: 500,
                    tokenExpired: true,
                    message: "Effettua nuovamente l'accesso"
                });
            } else {
                req.decoded = decoded;
                next();
            }
        });
    } else {
        res.send({
            success: false,
            status: 406, // Fprbidden
            message: 'User not Authenticated'
        });
    }
};
有人知道怎么帮我吗? 编辑:这是一个Chrome如何看到这两个请求的示例。屏幕截图,特别是指第一个被调用并生成404的屏幕截图

CORS在后端的处理方式如下

app.use(function (req, res, next) {

    if (req.headers.origin && (req.headers.origin.match("http:\/\/somewebsite.com.*") || req.headers.origin.match("http:\/\/localhost:8010") )) {
        res.header("Access-Control-Allow-Origin", req.headers.origin);
    }

    next();
});
另外,我正在添加需要调用的端点。这还利用MongoDB+Mongoose查询数据库并将内容返回到前端。我传递的参数是pageSize(每页有多少个元素)和当前页码

exports.getAds = (req, res) => {

  var criteria = req.body || {};
  var pageSize = criteria['pageSize'] ? Number(criteria['pageSize']) : undefined;
  var pageNumber = criteria['pageNumber'] ? Number(criteria['pageNumber']) : undefined;

  var sort = criteria.sort || { createdAt: 'desc' };

  if (criteria.customerName) criteria.customerName = { $regex: `.*${criteria.customerName}.*`, $options: 'i' };
  if (criteria.spentEuros) criteria.spentEuros.$gte = criteria.spentEuros;
  if (criteria.referralMail) criteria.referralMail = { $regex: `.*${criteria.referralMail}.*`, $options: 'i' };


  console.log(criteria);

  var columns = "customerName duration spentEuros";

  if (pageSize && pageNumber) {
    Adv.paginate(criteria, {
      page: pageNumber,
      limit: pageSize,
      select: columns,
      sort: sort
    }, function (err, result) {
      if (!err) res.status(200).send({ success: true, data: result });
      else res.status(500).send({ success: false, message: err });
    });
  } else {
    Adv.find(criteria)
      .select(columns)
      .sort(sort)
      .exec(function (err, result) {
        if (!err) res.status(200).send({ success: true, data: result });
        else res.status(500).send({ success: false, message: err });
      });
  }

};
EDIT2:问题的解决方案:在后端添加app.options侦听器(正如@slebetman所指出的)以及已经存在的app.get-one解决了这个问题

有趣的是:出于一个我仍然必须理解的原因,Angular.JS两次调用该端点


这听起来很像浏览器发送飞行前
OPTIONS
请求,然后是
GET
。检查正在使用的HTTP谓词,如果需要在端点上支持CORS,请确保正在处理
选项
(而不仅仅是
GET
)。(如果您不希望这是一个跨源请求,请检查页面的源代码相对于API调用的源代码,某些[协议、端口、域]似乎不同-如果它是一个
选项
调用。)

应用程序。使用
只注册中间件。您是否有处理该端点的
app.get
程序?当然有:第二次执行时,该端点将被正确调用并返回所需的值。YI406是不可接受的,与内容类型协商有关,不被禁止(403)。@GianmarcoF浏览器代码是否实际看到了
get
的结果?@GianmarcoF.-您能否将问题简化为一个人们可以复制并粘贴到自己的设置中以尝试帮助解决的问题?(上面已经很接近了,我想说,只是缺少了几个小的部分。)是的,它两次都被作为选项调用(由于CORS),但首先它得到404,然后它得到200。我已经添加了第一个的屏幕截图response@GianmarcoF. 我只看到你在做
app.get('/api/myPath/for/Having/Data',something.something调用)
。你还需要做
app.options('/api/myPath/for/Having/Data',something.something调用)
@GianmarcoF。--问题不在于CORS标题。问题是浏览器在GET请求之前发出选项请求。您正在正确处理标题。您没有处理选项requests@GianmarcoF. - 没有人叫它两次。有一个
OPTIONS
请求(只有一个),然后有一个
GET
请求(只有一个)。这就是需要飞行前的工作原理。有关详细信息,请参见链接的等级库。Re“无法读取未定义的属性
数据
”,这将是代码中相对简单的错误。“…即使请求执行两次,每次都会返回数据…”您不需要发送两次数据。发送一次,以响应
GET
<代码>选项(对于CORS)完全是关于标题的。@T.J.Crowder谢谢,我一定会看看规范!
app.use(function (req, res, next) {

    if (req.headers.origin && (req.headers.origin.match("http:\/\/somewebsite.com.*") || req.headers.origin.match("http:\/\/localhost:8010") )) {
        res.header("Access-Control-Allow-Origin", req.headers.origin);
    }

    next();
});
exports.getAds = (req, res) => {

  var criteria = req.body || {};
  var pageSize = criteria['pageSize'] ? Number(criteria['pageSize']) : undefined;
  var pageNumber = criteria['pageNumber'] ? Number(criteria['pageNumber']) : undefined;

  var sort = criteria.sort || { createdAt: 'desc' };

  if (criteria.customerName) criteria.customerName = { $regex: `.*${criteria.customerName}.*`, $options: 'i' };
  if (criteria.spentEuros) criteria.spentEuros.$gte = criteria.spentEuros;
  if (criteria.referralMail) criteria.referralMail = { $regex: `.*${criteria.referralMail}.*`, $options: 'i' };


  console.log(criteria);

  var columns = "customerName duration spentEuros";

  if (pageSize && pageNumber) {
    Adv.paginate(criteria, {
      page: pageNumber,
      limit: pageSize,
      select: columns,
      sort: sort
    }, function (err, result) {
      if (!err) res.status(200).send({ success: true, data: result });
      else res.status(500).send({ success: false, message: err });
    });
  } else {
    Adv.find(criteria)
      .select(columns)
      .sort(sort)
      .exec(function (err, result) {
        if (!err) res.status(200).send({ success: true, data: result });
        else res.status(500).send({ success: false, message: err });
      });
  }

};