2016-05-08 5 views
0

Ich bin sehr sehr fest in diesem "fast da" Art von Problem. Ich bin neu im Programmieren, kam aber gut zurecht, bis ich auf dieses Problem stieß.Warum funktioniert meine POST-Anfrage nicht in Knoten

Also habe ich diesen POST Anruf, um einen neuen Benutzer, den ich von Facebook mit Passpost.js bekomme, wenn die "ID" nicht existiert. Hier

ist die POST-Aufruf (mit "Anfrage" Modul):

passport.use(new FacebookStrategy({ 
    clientID: config.facebook.appID, 
    clientSecret: config.facebook.appSecret, 
    callbackURL: config.facebook.callbackURL, 
    profileFields: ['id', 'displayName', 'photos', 'emails', 'birthday', 'location', 'bio', 'likes.limit(100)'] 
}, 
function(accessToken, refreshToken, profile, done){ 
    userModel.findOne({'profileID':profile.id}, function(err, result){ 
     if(result){ 
      done(null, result); 
     } else { 
      request({ 
       url: 'http://localhost:3000/api/user', 
       qs: {id: 'profile.id',}, 
       method: 'POST', 
       json: { 
        fullname: profile.displayName, 
        profilePic: profile.photos[0].value || '', 
        email:  profile.emails[0].value || '', 
        birthday: profile._json.birthday || '', 
        location: profile._json.location.name || '', 
        about:  profile._json.bio || '', 
        likes:  profile._json.likes || '' 
       } 
      }, function(error, response, body){ 
       if(error) { 
        console.log(error); 
       } else { 
        console.log(response.statusCode, body); 
       } 
      }); 

     } 
    }) 


} 
) 
) 

Ich packte den POST Anruf auf meinem Router wie folgt aus:

apiRouter.post('/api/user', secureAPIPages, function(req, res, next){ 
    userModel.findOne({'profileID':req.query.id}, function(err, result){ 
     if(result){ 
      console.log('User exists already'); 
     } else { 

      var newUser = new userModel({ 
       profileID : res.query.id, 
       fullname : res.json.displayName, 
       profilePic : res.json.photos || '', 
       email  : res.json.emails || '', 
       birthday : res.json.birthday || '', 
       location : res.json.location || '', 
       about  : res.json.bio || '', 
       likes  : res.json.likes || '' 
      }); 

      newUser.save(function(err){ 
       console.log('User has been saved'); 
      }) 
     } 
    }) 
}) 

ich diese bekommen von der POST Aufruf : 302 undefiniert (302 ist der statusCode und undefined ist der Rumpf des POST-Aufrufs im Anforderungsmodul).

Das ist wirklich eine zweiteilige Frage:

1) Warum ist mein POST Aufruf funktioniert nicht? 2) Sieht meine apiRouter.post Route gut aus?

Es mag etwas sehr einfaches sein, aber ich habe unzählige Stunden damit verbracht, das zu debuggen, aber ich komme wirklich nicht weiter.

Ihre Hilfe wird dringend empfohlen.

Danke, Shayan

Antwort

2

Geradenennen 10, nachdem Sie Benutzer hinzugefügt haben

passport.use(new FacebookStrategy({ 
    // ommited 
}, 
function(accessToken, refreshToken, profile, done){ 
    userModel.findOne({'profileID':profile.id}, function(err, result){ 
     if(result){ 
      done(null, result); 
     } else { 
      request({ 
       // ommited 
      }, function(rErr, rResponse, rBody){ 
       //use rResponse or rBody, depends on request package 
       //you must pass new created user to `done` callback 
       done(rErr, rBody); // <== done from passport callback 
      }); 
     } 
    }) 
    }) 
) 
+0

Hey danke! Das hat mich noch einen Schritt weiter gebracht jetzt heißt es, mein req.body-Objekt sei undefiniert, ich könnte meinen Verstand verlieren, aber wenn du irgendwelche Vorschläge hast, wird es sehr geschätzt werden (übrigens wird req.body von res.json geändert, wie es angegeben wurde out von QoP in einem anderen Kommentar) –

+0

@Shayan aktualisiert –

+1

Begonnen zu arbeiten! Ich vermisste das Body-Parser-Modul zu lesen .body Objekt (duh) !!! Vielen Dank Mann, ich mache Ihre Antwort als die Antwort für diese als Das hat mir am meisten geholfen! –

2

Die Daten, die Sie über Anfrage Post einreichen ist in req.body, nicht in res.json.

diese

var newUser = new userModel({ 
       profileID : res.query.id, 
       fullname : res.json.displayName, 
       profilePic : res.json.photos || '', 
       email  : res.json.emails || '', 
       birthday : res.json.birthday || '', 
       location : res.json.location || '', 
       about  : res.json.bio || '', 
       likes  : res.json.likes || '' 
      }); 

sollte

var newUser = new userModel({ 
       profileID : req.query.id, 
       fullname : req.body.displayName, 
       profilePic : req.body.photos || '', 
       email  : req.body.emails || '', 
       birthday : req.body.birthday || '', 
       location : req.body.location || '', 
       about  : req.body.bio || '', 
       likes  : req.body.likes || '' 
      }); 
+0

Das hat nicht funktioniert mate. Ich habe das schon mal ausprobiert. Das gleiche Ergebnis leider erhalten –

+1

fehlte das Body-Parser-Modul lol. Vielen Dank für Ihre Antwort und Zeit, Kumpel! –

2

sein Was ist apiRouter? Ich hoffe, es ist die Instanz des Express-Objekts. Wie in irgendwo haben Sie Linie wie

var express = require('express'); 
var apiRouter = express.Router(); 

Mit dieser Annahme sieht die Strecke fein genug obwohl ratsam, Ihre Funktionen in einer anderen Datei zu verkapseln. in der Trennung von Ihrer api Schicht soetwas wie werde dazu beitragen, aus den Routen:

var controllers = require("../controllers/web"); 
var express = require('express'); 
var router = express.Router(); 

router.get('/', controllers.home.landing); 
router.get('/collections', controllers.collections.get_all_products_by_store); 
router.get('/register', controllers.login.register); 
router.get('/login, controllers.login.login_view); 
router.post('/store_city_details', controllers.home.store_city_details)  

Auch ist Ihr POST Anruf zu fein. Sie bekommen eine 302 Antwort vom Server:

HTTP 302. Der HTTP-Antwortstatuscode 302 Gefunden ist ein gemeinsamer Weg von URL-Umleitung durchführen. Eine HTTP-Antwort mit diesem Statuscode stellt zusätzlich eine URL im Feld für den Standortkopf zur Verfügung.HTTP 302 - Wikipedia, the free encyclopedia

Das einzige Stück des Codes, die

secureAPIPages 

Sie haben eine Middleware verwendet Sinn tut ist, dass Sie die 302-Umleitung Antwort sendet. Ihre Anfrage erreicht nicht einmal den gewünschten Endpunkt. Wenn Sie 200 StatusOkay zurückgegeben haben, würden Sie sicher sein, dass Ihre API funktioniert. Aber dann gibt es ein bisschen Verständnis für das Anfrage- und Antwortobjekt des Knotens.

die Zeile:

function(req, res, next) ... 

haben Sie Zugriff auf drei Parameter:

  • req: das Request-Objekt
  • res: das Antwortobjekt
  • nächste: Function - Dient zur Übertragung Steuerung zur nächsten Funktion in der Route.

Wenn es der Endpunkt Ihrer api ist das Antwortobjekt verwenden, um eine Antwort auf den Original-Beitrag Anruf zurück zu senden:

collections.get_cart_data = function (req, res) { 

    logger.info('[WEBSITE][API] in collections get_cart_data') 
    res.json(req.session.selected_products); // sends back a response in json format that is made of the selected_products we received in the request session object 
}; 

Ihr Code:

var newUser = new userModel({ 
       profileID : res.query.id, // I guess you want the value of the profile id in the request . Use req.query to access query values of the HTTP request 
       fullname : res.json.displayName, // this is some weird bit of code I just cant wrap my head around.. 
       profilePic : res.json.photos || '', // res.json is used to send a json response back to the api call 
       email  : res.json.emails || '', // What you are trying to do is tried to save that value in another object key value pair ?? 
       birthday : res.json.birthday || '', // There is no req.json method i am aware of so idk . these should be 
       location : res.json.location || '',// req.body . 
       about  : res.json.bio || '', 
       likes  : res.json.likes || '' 
      }); 

      newUser.save(function(err){ 
       console.log('User has been saved'); 
      }) 

gibt es verschiedene erf Methoden, die verwendet werden, um auf die verschiedenen Werte zuzugreifen, die im Anforderungsobjekt gesendet wurden. Zur Klarstellung: Die Werte, die Sie in Ihrem POST übergeben/GET-Aufruf an Dich im Request-Objekt zugänglich sind:

req.body: Der Zugriff auf Körperwerte, in POST-Aufruf verwendet req.query: Der Zugriff auf Abfrage Werte, req.params in GET-Aufruf verwendet: Der Zugriff auf Parameter,

So sollte Ihr api mehr wie in GET-Aufruf verwendet:

apiRouter.post('/api/user', secureAPIPages, function(req, res, next){ 
    userModel.findOne({'profileID':req.query.id}, function(err, result){ 
     console.log("MY REQUEST BODY OBJECT VALUES", req.body) // will show you the object you passed in " json:{} " of your POST call 
     console.log("MY REQUEST Query OBJECT VALUES", req.query) // will show {id: 'profile.id'} Please remove that trailing comma. Really got my ocd 
     console.log("MY REQUEST Params OBJECT VALUES", req.params) // would be empty {} 
     if(result){ 
      console.log('User exists already'); 
      res.send({"errmsg":"User exists already"})//send error response back 
     } else { 
      /* Write clean code, define objects separately*/ 
     var newUserDetails ={ 
       "profileID" : req.query.id, // using req.query here as the qs value in your post call passes a query string appended to the url . used for auth purposes 
       "fullname" : req.body.fullname, // Notice the use of "" for proper JSON structure. Use Jslint to verify your jsons 
       "profilePic" : req.body.profilePic || '', // Also notice I have changed the variable names 
       "email"  : req.body.email || '', // These need to match the key values as provided in POST call . 
       "birthday" : req.body.birthday || '', 
       "location" : req.body.location || '', 
       "about"  : req.body.about || '', 
       "likes"  : req.body.likes || '' 
      } 

      var newUser = new userModel(newUserDetails); 

      newUser.save(function(err){ 
       console.log('User has been saved'); 
       var response = { 
       "message" : " User has been saved", 
       "user" : newUserDetails 
       } 
       res.send(response); // will send the reponse object back to your frontend 
      }) 
     } 
    }) 
}) 
+0

Sie haben Recht, es sollte req.body statt req.json sein (QoP erwähnte das auch in einem der anderen Kommentare). Speichern Sie es direkt innerhalb des Codes funktioniert (wie Sie oben angegeben), aber was ich versuche es zu tun machen einen API-Server, so dass die Dinge, die ich für POST, GET usw. benötigen extern behandelt werden, so kann ich andere Clients leicht machen (z iOS, Android usw.). Aber es funktioniert nicht und außer dem Ändern der .json zu .body, sehe ich keine anderen Probleme und es sollte funktionieren, aber es ist nicht. Ich weiß nicht, was mir hier fehlt –

+0

Auch Ihre Annahme über apiRouter ist korrekt und secureAPIPages ist nur eine Funktion, die den Benutzer auf eine "API nicht autorisierte" Seite umleitet, wenn der Benutzer nicht existiert. Dies funktioniert auf den anderen GET-Routen, so dass es in Ordnung sein sollte. Ich habe es auch aus meinem Debugging entfernt, also ist das nicht das Problem - nur um das Problem weiter zu isolieren –

+0

Es begann zu arbeiten! Bitte sehen Sie die akzeptierte Antwort.Sehr schätzen Sie Ihr Feedback und Ihre Zeit. Vielen Dank Alter! –

Verwandte Themen