REST节点服务器有时运行两次代码

好吧,这似乎有点奇怪。 但是我有一个运行我的REST API的Node服务器。

我从我的angular度应用程序调用API ,但有时如果我只是留在同一页上最后一个已知的请求执行多次。

我开始以为这只是一个问题,但是现在我经历了很长一段时间以后,我发现它不pipe我的应用程序在哪个页面上。

有趣的是,在我的前端控制台(Chrome)中,调用并没有被执行多次。

我的API包含了很多路由文件,但主要的结构如下所示:

Server.js

  // BASE SETUP // ============================================================================= var express = require('express'), bodyParser = require('body-parser'); var app = express(); var router = express.Router(); var es = require('express-sequelize'); var multer = require('multer'); var Excel = require("exceljs"); var ex = require('xlsjs'); var stream = require('stream'); var fs = require('fs'); var XLSX = require('xlsx'); var async = require('async'); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); // ============================================================================= //Secure app.all('/*', function (req, res, next) { // CORS headers res.header("Access-Control-Allow-Origin", "*"); // restrict it to the required domain res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS'); // Set custom headers for CORS res.header('Access-Control-Allow-Headers', 'Content-type,Accept,X-Access-Token,X-Key'); if (req.method == 'OPTIONS') { res.status(200).end(); } else { next(); } }); var env = app.get('local') == 'development' ? 'dev' : app.get('env'); var port = process.env.PORT || 8080; var Sequelize = require('sequelize'); // db config var env = "local"; var config = require('./database.json')[env]; var password = config.password ? config.password : null; // initialize database connection var sequelize = new Sequelize( config.database, config.user, config.password, { port: config.port, host: config.server, logging: console.log, define: { timestamps: false } } ); var user = {}; var done = {is_complete: false}; app.use(multer({ dest: './uploads/', rename: function (fieldname, filename) { return filename + Date.now(); }, onFileUploadStart: function (file) { console.log(file.originalname + ' is starting ...') }, onFileUploadComplete: function (file) { //Redirects request to path } })); var auth = require('./auth.js')(express, sequelize, router); app.all('/api/*', [require('./middlewares/validateRequest')]); app.use('/', router); app.use(auth); //Init models var division_model = require('./lb_models/division/division_model')(express, sequelize, router, user, async); var location_model = require('./lb_models/division/Location')(express, sequelize, router, user, async); var user_model = require('./lb_models/user/user_model')(express, sequelize, router, user, async); var title_model = require('./lb_models/title/Title')(express, sequelize, router, user, async); var login_stat = require('./lb_models/user/Login')(express, sequelize, router, user, async); var quote_model = require('./lb_models/Quote')(express, sequelize, router, user, async); var organization_model = require('./lb_models/user/Organization')(express, sequelize, router, user, async); var competence_model = require('./lb_models/competence/Competence')(express, sequelize, router, user, async, multer, done); var competenceCategory_model = require('./lb_models/competence/CompetenceCategory')(express, sequelize, router, user, async, multer, done); var level_model = require('./lb_models/competence/Level')(express, sequelize, router, user, async, multer, done); /* Admin dashboard */ var admin_dash = require('./lb_models/dashboard/AdminDashboard')(express, sequelize, router, user, async); /* Modules */ var category_model = require('./lb_models/module/Category')(express, sequelize, router, user, async); var module_type = require('./lb_models/module/Type')(express, sequelize, router, user, async); var module_model = require('./lb_models/module/Module')(express, sequelize, router, user, async); var component_model = require('./lb_models/module/Component')(express, sequelize, router, user, async); /* Academy */ var academy_model = require('./lb_models/academy/Academy')(express, sequelize, router, user, async); var academyModule_model = require('./lb_models/academy/AcademyModule')(express, sequelize, router, user, async); var academy_team = require('./lb_models/academy/Team')(express, sequelize, router, user, async); var academy_course_model = require('./lb_models/academy/AcademyCourse')(express, sequelize, router, user, async); var user_academy_model = require('./lb_models/academy/UserAcademy')(express, sequelize, router, user, async); /* Stat */ var comp_stat = require('./lb_models/competence/CompetenceStat')(express, sequelize, router, user, async); var userComp = require('./lb_models/competence/UserCompetence')(express, sequelize, router, user, async); /* Screening */ var screening_model = require('./lb_models/screening/Screening')(express, sequelize, router, user, async); /* Testview */ var answers = require('./lb_models/testview/Answer')(express, sequelize, router, user, async); var medals = require('./lb_models/testview/Medal')(express, sequelize, router, user, async); /* Course */ var courses = require('./lb_models/course/Course')(express, sequelize, router, user); var reasons = require('./lb_models/course/Reason')(express, sequelize, router, user); /* Material */ var material = require('./lb_models/material/Material')(express, sequelize, router, user); var profileDocument = require('./lb_models/material/ProfileDocument')(express, sequelize, router, user); /* Activity */ var activities = require('./lb_models/activity/Activity')(express, sequelize, router, user); /* Analytics */ var activity_model = require('./lb_models/analytics/Activity')(express, sequelize, router, user, async); var academyStat_model = require('./lb_models/analytics/Academy')(express, sequelize, router, user, async); var teamStat_model = require('./lb_models/analytics/Team')(express, sequelize, router, user, async); var academyReport_model = require('./lb_models/analytics/Report')(express, sequelize, router, user, async); var analytics_user_model = require('./lb_models/analytics/User')(express, sequelize, router, user, async); var analytics_overview = require('./lb_models/analytics/Overview')(express, sequelize, router, user, async); var analytics_survey = require('./lb_models/analytics/Survey')(express, sequelize, router, user, async); /* Self development */ var selfDevelopment_model = require('./lb_models/analytics/SelfDevelopment')(express, sequelize, router, user, async); /* Benchmark */ var academyBenchmark_model = require('./lb_models/analytics/AcademyBenchmark')(express, sequelize, router, user, async); /* Jeopardy */ var jeopardy_model = require('./lb_models/jeopardy/jeopardy')(express, sequelize, router, user, async); app.use(division_model); app.use(location_model); app.use(user_model); app.use(title_model); app.use(quote_model); app.use(organization_model); app.use(login_stat); app.use(competence_model); app.use(competenceCategory_model); app.use(level_model); /* Admin Dashboard */ app.use(admin_dash); /* Modules */ app.use(category_model); app.use(module_type); app.use(module_model); app.use(component_model); /* Academy */ app.use(academy_model); app.use(academy_team); app.use(academyModule_model); app.use(academy_course_model); app.use(user_academy_model); /* Screening */ app.use(screening_model); /* Stat */ app.use(comp_stat); app.use(userComp); /* Testview */ app.use(answers); app.use(medals); /* Course */ app.use(courses); app.use(reasons); /* Material */ app.use(material); app.use(profileDocument); /* Activity */ app.use(activities); /* Analytics */ app.use(activity_model); app.use(academyStat_model); app.use(teamStat_model); app.use(academyReport_model); app.use(analytics_user_model); app.use(analytics_overview); app.use(analytics_survey); /* Self development */ app.use(selfDevelopment_model); /* Benchmark */ app.use(academyBenchmark_model); /* Jeopardy */ app.use(jeopardy_model); // If no route is matched by now, it must be a 404 app.use(function (req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err); }); // START THE SERVER app.listen(port); console.log('Magic happens on port ' + port); 

谁能告诉我为什么会发生这种情况? 这是一个很大的问题,因为我的创build语句会在我的数据库中创build多个项目!

附加信息

好吧,我试了一下。 请求将再次运行,如果响应未决(意思是我不会返回一个响应?)

这里是我的猜测,尽pipe你的问题缺乏足够的细节 – 许多浏览器会在响应超时的时候自动重试XHR请求。 他们会这样做的请求,应该是幂等和安全的重试,包括GET。 我看到这个,当我延迟响应,因为我有一个交互式debugging器在断点上暂停服务器代码。 如果你的快递没有足够快的响应,angular度可能会重试请求,所以这可能是你注意到的。

请检查这个:

  • 你启用了CORS,所以,如果你做了一个需要cors的请求,那么浏览器首先会做一个OPTIONS请求,然后是请求(GET,POST,PUT或DELETE)。

看起来这是因为浏览器做了Preflight OPTION请求 :

…“preflighted”请求首先通过OPTIONS方法向另一个域上的资源发送HTTP请求,以确定实际的请求是否安全发送

所以, app.all匹配所有的请求方法,这就是为什么你有双重代码执行。

解:

我强烈build议您使用适当的语义来指定请求方法。 使用GET仅用于获取数据(它不应该改变服务器端的状态,POST – 仅用于更改服务器端的数据。否则,您的网站可能会被CSRF攻击(请参阅“GET场景”)攻击。

当我使用app.all('*', ...和通过POST方法请求时,同样的事情发生在我身上,分离了app.get()app.post() ,就再也没有发生过。

 var router = function(res, req){ console.log(req.method); }; // run twice app.all('*', router); // run once app.get('*', router); app.post('*', router); 
  • 版本express@4.13.4