我非常坚持这种“几乎存在”的问题。我是编程新手,但在我遇到这个问题之前一直很好。
所以,我有这个POST调用来放置一个新用户,如果“id”不存在,我可以使用Passpost.js从Facebook获得。
这是POST调用(使用“request”模块):
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);
}
});
}
})
}
)
)
我正在我的路由器上抓取POST调用:
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');
})
}
})
})
我从POST调用得到这个:302 undefined(302是statusCode,未定义是请求模块中POST调用的主体)。
这实际上是一个两部分问题:
1)为什么我的POST电话无效? 2)我的apiRouter.post路线看起来不错吗?
这可能是非常简单的事情,但我花了无数个小时来尝试调试这个,但我真的没有到达任何地方。
我们非常推荐您的帮助。
谢谢, 砂眼
答案 0 :(得分:2)
您通过请求发布的数据位于req.body中,而不是res.json。
此
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 || ''
});
应该是
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 || ''
});
答案 1 :(得分:2)
什么是apiRouter? 我希望它是快递对象的实例。就像在某个地方你有像
这样的行var express = require('express');
var apiRouter = express.Router();
根据这个假设,虽然建议将函数封装在另一个文件中,但该路径看起来还不错。将有助于将api层与路线隔离开来:
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)
你的POST也很好。您从服务器获得302响应:
HTTP 302. HTTP响应状态代码302 Found是一种常见的方式 执行URL重定向。具有此状态代码的HTTP响应 还将在位置标题字段中提供URL。 HTTP 302 - Wikipedia, the free encyclopedia
你的代码中唯一没有意义的是
secureAPIPages
您使用了向您发送302重定向响应的中间件。您的请求甚至没有到达您想要的端点。 如果它已返回200 StatusOkay,您将确保您的API有效。 但是那时理解了节点的请求和响应对象。
行:
function( req, res, next) ...
您可以访问三个参数:
如果是api的端点,请使用响应对象将回复发送回原始帖子:
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
};
您的代码:
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');
})
有不同的req方法用于访问请求对象中发送的不同值。 澄清:您在POST / GET调用中传递的值可以在请求对象中访问:
req.body:访问POST调用中使用的正文值 req.query:访问GET调用中使用的查询值 req.params:访问GET调用中使用的参数
所以你的api应该更像:
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
})
}
})
})
答案 2 :(得分:2)
添加用户
后,只需致电done()
即可
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
});
}
})
})
)