node.js表示一个非常奇怪的行为

我有一个运行的Express服务器。

我所做的是从HTML上传Excel文件,然后快速parsing该文件,并做一些计算。

在Excel文件中,每行都有关于用户地址的信息。

对于每个地址,我们的快递服务器将使用谷歌地图地理编码API来计算经度和纬度。

但是,由于Google不接受每秒超过50个地理编码API的请求,所以我不得不使用settimeout来延迟计算。

例如,如果Excel文件有50个地址,所以我必须在每个地址上使用settimeout来避免这个速率限制。

这里是我的代码使用settimeout并计算纬度,经度

createFromFile(req, res) { var form = new formidable.IncomingForm(); return form.parse(req, function (err, fields, files) { if (err) return res.status(500).json({error: err.message}) var workbook = new exceljs.Workbook(); return workbook.xlsx.readFile(files.excelfile.path).then(function() { // use workbook var worksheet = workbook.getWorksheet(1) var data = [] for (var i=2; i<=worksheet.rowCount; i++) { data.push({ from_name: worksheet.getCell('A'+i).value + '', from_address: worksheet.getCell('B'+i).value + '', from_phone: worksheet.getCell('C'+i).value + '', receiver_name: worksheet.getCell('D'+i).value + '', receiver_address: worksheet.getCell('E'+i).value + '', receiver_phone: worksheet.getCell('F'+i).value + '', note: worksheet.getCell('H'+i).value + '' }) } var delay = function(t) { return new Promise(function(resolve) { setTimeout(resolve, t) }) } return Promise.all(data.map(function(item, i) { return function() { return delay(750*i).then(function() { winston.log('debug', 'process for item '+i) return geocoder.geocode(item.from_address).then(function(geo_data) { data[i].from_coord = { lat: geo_data[0].latitude, lng: geo_data[0].longitude } return geocoder.geocode(item.receiver_address).then(function(geo_data) { data[i].receiver_coord = { lat: geo_data[0].latitude, lng: geo_data[0].longitude } }) }) .catch(function(geo_error) { winston.log('error', 'geo_error', {error: geo_error}) throw new Error('Address in line ' + i + ' is not valid') }) }) }() })) .then(function() { winston.log('debug', 'we are done calculating location') return res.status(201).json(data) }) }) .catch(function(e) { winston.log('error', 'an error occurred') return res.status(500).json({error: e.message}) }) }) } 

下面是我的代码来调用这个Express API,我使用React做前端工作&使用javascript fetch api向服务器请求。

 startUploadFile() { this.props.showLoader() let data = new FormData() data.append('excelfile', this.state.selectedFile) data.append('name', 'excelfile') var me = this fetch(Const.restServer + '/create-from-file', { headers: { 'Access-Token': this.props.access_token, }, method: 'POST', body: data }) .then(function(r) { return r.json() }) .then(function(r) { if (r.hasOwnProperty('error')) throw new Error(r.error) me.props.hideLoader() me.props.showDialog('success', 'Process Complete') }) .catch(function(e) { console.log(e) me.props.hideLoader() me.props.showDialog('error', e.message) }) } 

我的问题是,当我使用上面的代码上传浏览器上的文件,我看到两个请求中的快速日志文件。 像这样的东西:

快速服务器日志文件 我也会提供我的代码来logging每个请求的信息

 app.use(function(req, res, next) { winston.log('debug', 'call api:', { api: req.url, requestMethod: req.method }) res.header("Access-Control-Allow-Origin", "*"); res.header( "Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Access-Token, Web-Admin-Request" ); next() }); function isAuthenticated(req, res, next) { /** ** Rest API Middleware check if access_token is valid */ let accessToken = req.body.accessToken || req.get('Access-Token') // bunch of codes to check accessToken next() } app.post('/order/create-from-file', isAuthenticated, orderController.createFromFile); 

我不明白为什么会发生这种情况。 如果我使用邮递员&select一个文件&上传,它工作正常 – 只是在日志中的一个请求。

谁能告诉我是什么原因。 我觉得这是一个快递的错误。 我的Express版本是4.15.2

您的代码添加到请求的Access-Token请求标头会触发浏览器在尝试POST请求之前发送CORS预检OPTIONS请求。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests给出了更多的细节,但其要点是,只要您的代码添&#x52A0;Access-Token标头的请求,没有您可以防止浏览器进行额外的预检OPTIONS请求,因为这是浏览器自动作为CORS协议的一部分执行的操作。

您使用Postman时没有看到额外请求的原因是,它不会执行CORS预检OPTIONS请求 – 只有浏览器才会发送请求,并且仅用于由XHR /从浏览器中运行的前端JavaScript代码提取的请求(邮差不是)。

那么,最后我可以通过将'Access-Token'传递到请求体而不是请求头(现在,我的服务器总是只接收一个请求)来解决这个问题。 感谢@sideshowbarker,因为你的评论触发我做这个方法。

我仍然认为这个问题是Express中的一个错误,但是因为它并没有出现在我的本地开发环境中,所以我不会向他们发送报告。