Мы разрабатываем приложение, в котором мы используем Firebase в качестве базы данных и выражаем как промежуточное программное обеспечение/бэкэнд для маршрутизации наших API RESTful, который используется нашим Front-end, разработанным в Reactjs.FIREBASE ПРЕДУПРЕЖДЕНИЕ: Исключение было вызвано обратным вызовом пользователя. Ошибка: не удается установить заголовки после их отправки.
Ниже то, что наш файл server.js выглядит следующим образом:
var express = require('express');
var app = express();
//Used for getting POST variables from forms as well as query parameters
var bodyParser = require('body-parser');
var validator = require('express-validator');
//Contains all the routes
var routes = require('./routes/routes');
var path = require('path');
//Used for serving jade files
app.set('view engine', 'jade');
//For serving static resources like scripts, styleSheets, html
app.use(express.static(__dirname + '/views'));
app.all('/*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Methods", "POST, GET");
next();
});
// configure app to use bodyParser()
// this will let us get the data from a POST
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(validator({
customValidators: {
onlyAlphabets: function(value) {
if (value.match('^[a-zA-Z ]*$')) {
return true;
} else {
return false;
}
},
password: function(value) {
if (value.length >= 6 && value.length <=25 && value.match('^[\x20-\x7F]*$')) {
return true;
} else {
return false;
}
}
}
}));
app.use(routes);
var port = process.env.PORT || 8080; //Set our port
app.listen(port);
console.log('Magic happens on port ' + port);
Ниже приведен код для маршрутизации, который присутствует в route.js:
var express = require('express');
var views = __dirname;
// Node.js path library - https://nodejs.org/api/path.html
var path = require('path');
var Firebase = require("firebase");
var myFirebaseRef = new Firebase("https://crackling-inferno-8454.firebaseio.com/vendor_details");
var router = express.Router();
//Password Encryption and decryption helpers
var hashFunction = require('../helpers/encrypt');
// middleware to use for all requests
router.use(function(req, res, next) {
// do logging
console.log('Something is happening.');
next(); // make sure we go to the next routes and don't stop here
});
router.get('/', function(req, res) {
res.render('vendor_form');
});
router.route('/get_vendors').get(function(request, response) {
myFirebaseRef.on("value", function(snapshot) {
var store = snapshot.val();
// Looping to get the firebaseId generated while push
for(var key in store){
store[key].id = key; // Store firebaseID generated during push to store in JSON object
}
response.send(Object.keys(store).map(function(k) { return store[k]; }));
}, function (errorObject) {
response.send("The read failed: " + errorObject.code);
});
});
router.route('/post_vendor').post(function(request, response) {
request.checkBody({
'vendor_name': {
notEmpty : {
errorMessage: 'Please enter a vendor\'s name'
},
onlyAlphabets : {
errorMessage: 'Please enter only alphabets'
}
},
'enterprise_name': {
notEmpty : {
errorMessage: 'Please enter an enterprise\'s name'
},
onlyAlphabets : {
errorMessage: 'Please enter only alphabets'
}
},
'vendor_email': {
notEmpty : {
errorMessage: 'Please enter your email address'
},
isEmail : {
errorMessage: 'please enter an appropriate email format'
}
},
'vendor_password': {
notEmpty : {
errorMessage: 'Please enter a password'
},
password: {
errorMessage: 'Password length should be between 6-25 characters'
}
},
'food_preference': {
notEmpty: {
errorMessage: 'You must select atleast one food preference'
}
}
});
var errors = request.validationErrors();
// var onComplete = function(error) {
// if (error) {
// response.send('Failed to add stats to the database');
// return false;
// } else {
// // response.render('vendor_form', { success: true });
// response.send('Success');
// return true;
// }
// };
if (errors) {
response.send(errors);
// response.render('vendor_form', { error: errors });
return false;
} else {
myFirebaseRef.push().set({
'id': Firebase.ServerValue.TIMESTAMP,
'vendor_name': request.body.vendor_name,
'enterprise_name': request.body.enterprise_name,
'vendor_email': request.body.vendor_email,
'vendor_password': hashFunction.encrypt(request.body.vendor_password),
'food_preference': request.body.food_preference
}, function(err) {
if (err) {
response.send('Failed to add stats to the database');
} else {
response.send('Success');
}
});
return true;
}
});
module.exports = router;
Ниже приведен код, мы добавили в интерфейсе для размещения данных. Мы также используем WHATWG-выборки пакета:
httpservice.js:
var Fetch = require('whatwg-fetch');
var baseUrl = 'http://192.168.1.134:8080';
var Service = {
get: function(url) {
console.log('MAKING A GET REQUEST');
return fetch(baseUrl + url)
.then(function(response) {
return response.json();
});
},
post: function(url, postData) {
console.log('MAKING A POST REQUEST');
return fetch(baseUrl + url, {
headers: {
'Content-Type': 'application/json'
},
method: 'POST',
body: JSON.stringify(postData)
}).then(function(response) {
return response;
});
}
}
module.exports = Service;
VendorForm.js (React файл компонента)
HTTP.post('/post_vendor', httpRequestBody)
.then(function(response) {
console.log(response);
}.bind(this));
Мы начинаем наш сервер, который предоставляет RESTful API, разработанный в FIREBASE + EXPRESS через nodemon. Это ошибка, которую мы получаем, когда мы размещаем наши:
FIREBASE WARNING: Exception was thrown by user callback. Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:344:11)
at ServerResponse.header (/var/www/tutorials/express_firebase/node_modules/express/lib/response.js:718:10)
at ServerResponse.send (/var/www/tutorials/express_firebase/node_modules/express/lib/response.js:163:12)
at ServerResponse.json (/var/www/tutorials/express_firebase/node_modules/express/lib/response.js:249:15)
at ServerResponse.send (/var/www/tutorials/express_firebase/node_modules/express/lib/response.js:151:21)
at /var/www/tutorials/express_firebase/routes/routes.js:30:12
at /var/www/tutorials/express_firebase/node_modules/firebase/lib/firebase-node.js:200:710
at ec (/var/www/tutorials/express_firebase/node_modules/firebase/lib/firebase-node.js:52:165)
at ac (/var/www/tutorials/express_firebase/node_modules/firebase/lib/firebase-node.js:31:216)
at bc (/var/www/tutorials/express_firebase/node_modules/firebase/lib/firebase-node.js:30:1259)
at Ji.h.Mb (/var/www/tutorials/express_firebase/node_modules/firebase/lib/firebase-node.js:220:440)
at X.set (/var/www/tutorials/express_firebase/node_modules/firebase/lib/firebase-node.js:256:335)
at /var/www/tutorials/express_firebase/routes/routes.js:96:24
at Layer.handle [as handle_request] (/var/www/tutorials/express_firebase/node_modules/express/lib/router/layer.js:95:5)
at next (/var/www/tutorials/express_firebase/node_modules/express/lib/router/route.js:131:13)
at Route.dispatch (/var/www/tutorials/express_firebase/node_modules/express/lib/router/route.js:112:3)
/var/www/tutorials/express_firebase/node_modules/firebase/lib/firebase-node.js:52
(d="0"+d),c+=d;return c.toLowerCase()}var zd=/^-?\d{1,10}$/;function td(a){return zd.test(a)&&(a=Number(a),-2147483648<=a&&2147483647>=a)?a:null}function ec(a){try{a()}catch(b){setTimeout(function(){R("Exception was thrown by user callback.",b.stack||"");throw b;},Math.floor(0))}}function S(a,b){if(t(a)){var c=Array.prototype.slice.call(arguments,1).slice();ec(function(){a.apply(null,c)})}};function Ad(a){var b={},c={},d={},e="";try{var f=a.split("."),b=Pb(id(f[0])||""),c=Pb(id(f[1])||""),e=f[2],d=c.d||{};delete c.d}catch(g){}return{oh:b,Dc:c,data:d,ah:e}}function Bd(a){a=Ad(a).Dc;return"object"===typeof a&&a.hasOwnProperty("iat")?z(a,"iat"):null}function Cd(a){a=Ad(a);var b=a.Dc;return!!a.ah&&!!b&&"object"===typeof b&&b.hasOwnProperty("iat")};function Dd(a){this.Y=a;this.g=a.n.g}function Ed(a,b,c,d){var e=[],f=[];Na(b,function(b){"child_changed"===b.type&&a.g.Ad(b.Le,b.Ma)&&f.push(new H("child_moved",b.Ma,b.Ya))});Fd(a,e,"chi
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:344:11)
at ServerResponse.header (/var/www/tutorials/express_firebase/node_modules/express/lib/response.js:718:10)
at ServerResponse.send (/var/www/tutorials/express_firebase/node_modules/express/lib/response.js:163:12)
at ServerResponse.json (/var/www/tutorials/express_firebase/node_modules/express/lib/response.js:249:15)
at ServerResponse.send (/var/www/tutorials/express_firebase/node_modules/express/lib/response.js:151:21)
at /var/www/tutorials/express_firebase/routes/routes.js:30:12
at /var/www/tutorials/express_firebase/node_modules/firebase/lib/firebase-node.js:200:710
at ec (/var/www/tutorials/express_firebase/node_modules/firebase/lib/firebase-node.js:52:165)
at ac (/var/www/tutorials/express_firebase/node_modules/firebase/lib/firebase-node.js:31:216)
at bc (/var/www/tutorials/express_firebase/node_modules/firebase/lib/firebase-node.js:30:1259)
at Ji.h.Mb (/var/www/tutorials/express_firebase/node_modules/firebase/lib/firebase-node.js:220:440)
at X.set (/var/www/tutorials/express_firebase/node_modules/firebase/lib/firebase-node.js:256:335)
at /var/www/tutorials/express_firebase/routes/routes.js:96:24
at Layer.handle [as handle_request] (/var/www/tutorials/express_firebase/node_modules/express/lib/router/layer.js:95:5)
at next (/var/www/tutorials/express_firebase/node_modules/express/lib/router/route.js:131:13)
at Route.dispatch (/var/www/tutorials/express_firebase/node_modules/express/lib/router/route.js:112:3)
[nodemon] app crashed - waiting for file changes before starting...
По ошибке, мы знаем, что некоторые обратного вызова установки заголовка дважды, но не уверен, как это происходит. Был через несколько вопросов переполнения стека, но до сих пор не нашел решения. Любая помощь будет оценена по достоинству. Спасибо в ожидании.
Выполняется ли 'myFirebaseRef.on (« значение », fn)' огонь более одного раза? –
@BenFortune Согласно вашему предложению, я сделал консоль внутри myFirebaseRef.on ("value", fn). Он работает отлично на некоторое время. Но когда он падает, перед сбоем console.log() вызывается дважды. Это означает, что функция вызывается дважды. Но приложение падает на POST. Мы написали myFirebaseRef.on («значение», fn) <--- функция для get. Полностью смущен, что происходит. Спасибо, что указали эту штуку, хотя и жаль, что ответили поздно. –