使用PhantomJS处理多个用户请求到多个远程Web表单

我使用NightmareJS创build了一个ExpressJS应用程序,它有一个表单,当我们填写表单并提交时,它将请求发送给一些远程表单并计算数据并返回这些结果。 但问题是只有当单个客户提交表单时才有效。 当多个客户同时提交表单时,它不起作用。 这可能是什么原因以及如何解决这个问题?

前端JS脚本

$(document).ready(function () { $("#calculate-form").submit(function (event) { var request; if (request) { request.abort(); } var $form = $(this); var $inputs = $form.find("input, select, button, textarea"); var serializedData = $form.serialize(); $inputs.prop("disabled", true); form1(request, serializedData, $inputs, '/example1', '#form1'); function form1(request, serializedData, inputs, appUrl, displayElement) { request = $.ajax({ url: appUrl, type: "post", data: serializedData }); request.done(function (response) { $(displayElement).text(response.value); form2(request, serializedData, $inputs, '/example2', '#form2'); function form2(request, serializedData, inputs, appUrl, displayElement) { request = $.ajax({ url: appUrl, type: "post", data: serializedData }); request.done(function (response) { $(displayElement).text(response.value); }); request.fail(function (jqXHR, textStatus, errorThrown) { console.log("Failed"); }); } }); request.fail(function (jqXHR, textStatus, errorThrown) { console.log("Failed"); }); } event.preventDefault(); }); }); 

ExpressJS索引脚本

 var express = require('express'); var app = express(); var phantom = require('phantom'); var bodyParser = require('body-parser'); var Nightmare = require('nightmare'); app.use(bodyParser.urlencoded({ extended: true })); app.set('port', (process.env.PORT || 5000)); app.use(express.static(__dirname + '/')); app.engine('html', require('ejs').renderFile); app.get('/', function (request, response) { response.render('index.html'); }); app.listen(app.get('port'), function () { console.log('Scrapper is running on port', app.get('port')); }); require('./form1')(app, Nightmare); require('./form2')(app, Nightmare); 

ExpressJS form1脚本

 module.exports = function (app, Nightmare) { var nightmare1 = Nightmare({ show: true }); app.post('/example1', function (req, res) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); res.setHeader('Content-Type', 'application/json'); try { if (req.method === 'POST') { var requestParams = req.body; nightmare1 .goto('https://example1.com/form') .evaluate(function () { var select = document.querySelector('#RepaymentMethod'); select.value = "1"; select.dispatchEvent(new Event('change')); }) .wait("#formbtn-1") .evaluate(function () { document.getElementById('inputfield_1').value = "inputfield-1-Value"; document.getElementById('btnSubmitform').click(); }) .wait("#resultvalue") .evaluate(function () { var str = document.querySelector('#resultvalue').innerText; return res; }) .end() .then(function (form1) { res.send({value: form1}); nightmare1.halt(); }) .catch(function (error) { res.send({'error': error}); nightmare1.halt(); }); } } catch (err) { res.sendStatus(400).send(err); nightmare1.halt(); process.exit(); } }); } 

ExpressJS form2脚本

 module.exports = function (app, Nightmare) { var nightmare2 = Nightmare({ show: true }); app.post('/example2', function (req, res) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); res.setHeader('Content-Type', 'application/json'); try { if (req.method === 'POST') { var requestParams = req.body; nightmare2 .goto('https://example2.com/form') .evaluate(function () { var select = document.querySelector('#RepaymentMethod'); select.value = "10"; select.dispatchEvent(new Event('change')); }) .wait("#formbtn-1") .evaluate(function () { document.getElementById('inputfield_1').value = "inputfield-1-Value"; document.getElementById('inputfield_2').value = "inputfield-2-Value"; document.getElementById('btnSubmitform').click(); }) .wait("#resultvalue") .evaluate(function () { var str = document.querySelector('#resultvalue').innerText; return res; }) .end() .then(function (form2) { res.send({value: form2}); nightmare2.halt(); process.exit(); }) .catch(function (error) { res.send({'error': error}); nightmare2.halt(); process.exit(); }); } } catch (err) { res.sendStatus(400).send(err); nightmare2.halt(); process.exit(); } }); } 

根据你发布的例子,你试图在多个请求中重复使用相同的Nightmare实例。 这将不起作用,如果您有多个请求进来,稍后请求的操作将被添加到当前正在执行的上下文中。 这是更复杂的,因为你也是.end()的实例,使初始请求后的恶梦实例不可用。

如果将“恶梦”实例化为“快速post方法,则可能会有更好的运气,但请注意:此方法不能很好地缩放。