2016-02-19 47 views
2

我們正在開發我們正在使用火力地堡作爲數據庫,並表示作爲中間件/後端路由的應用在我們的REST API,它是用來通過我們的前端在Reactjs開發的。火力警告:異常是由用戶回調拋出。錯誤:無法設置頭後,他們被送到

下面是我們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(陣營組件文件)

HTTP.post('/post_vendor', httpRequestBody) 
.then(function(response) { 
     console.log(response); 
}.bind(this)); 

我們先從它提供的RESTful API中火力開發我們的服務器+通過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... 

按照錯誤,我們知道一些回調設置頭兩次,但不知道它是怎麼發生的。經歷了很少的堆棧溢出問題,但仍未找到解決方案。任何幫助,將不勝感激。感謝預期。

+1

是否'myFirebaseRef.on( 「值」,FN)'火不止一次? –

+0

@BenFortune按照你的建議,我做內部myFirebaseRef.on控制檯(「值」,FN)。它工作得很好。但是,當它崩潰之前,崩潰console.log()被調用兩次。這意味着該函數被調用兩次。但是,應用程序在POST上崩潰。我們已經寫myFirebaseRef.on( 「值」,FN)<---爲get函數。對發生的事情完全混淆。謝謝你指出這件事,但很抱歉,遲到回覆。 –

回答

4

如果你看到你的堆棧跟蹤

at /var/www/tutorials/express_firebase/routes/routes.js:30:12 

這是第30行中的文件route.js

response.send(Object.keys(store).map(function(k) { return store[k]; })); 

你需要改變方法ononce,否則你的回調函數被觸發,每次有更新到您的數據,

router.route('/get_vendors').get(function(request, response) { 
    myFirebaseRef.on("value", function(snapshot) { 

打破你的反應,當你調用POST方法,因爲頭被符合30

見參考文獻https://firebase.google.com/docs/database/server/retrieve-data#section-reading-once

基本上已經發給你與once方法做的是去除值宣讀後回調。

+0

有同樣的問題。完美的修復和有意義的一次簡單的改變,一次也爲我做了詭計! –

相關問題