node.js - 如何使用请求将 FormData 从 Node/Express 发送到另一个应用程序(Node/Express)
问题描述
我有一个在 localhost:8000 上运行的前端网站(ejs 和 node/express)(如果这有帮助)和在 localhost:8010 上运行的后端服务器(node/express)(ps 我的数据库在后端)。我正在尝试使用护照实现社交登录(fb、google 等),它工作得很好。但是我想将社交登录凭据保存在数据库中(我正在使用猫鼬) (当然在后端服务器中/在后端服务器上)
并且我的 Passport 应用程序在前端(快递)
还有我执行的所有CRUD操作网页就像一个魅力
我在前端使用请求模块将http请求发送到后端服务器
现在我正在做的是
前端服务器-
passport.use(new FacebookStrategy({
clientID: process.env.FB_CLIENT_ID || 'its a secret',
clientSecret: process.env.FB_CLIENT_SECRET || 'its a secret',
callbackURL: `${process.env.BASE_URL}/auth/callback/facebook` || '/auth/callback/facebook',
profileFields: ['name', 'email', 'link', 'locale'],
passReqToCallback: true
}, (req, accessToken, refreshToken, profile, cb) => {
const form = new FormData();
form.append('socialLogin', 'facebook');
form.append('facebook', profile.id);
form.append('accessToken', accessToken);
form.append('avatar', `https://graph.facebook.com/${profile.id}/picture?type=large`);
form.append('email', profile._json.email);
form.append('username', `${profile.name.givenName}${profile.name.familyName}`);
// const option = {
// socialLogin: 'facebook',
// facebook: profile.id,
// tokens: [{
// kind: 'facebook',
// accessToken
// }],
// avatar: `https://graph.facebook.com/${profile.id}/picture?type=large`,
// email: profile._json.email,
// username: `${profile.name.givenName} ${profile.name.familyName}`
// };
request({
method: 'POST',
dataType: 'JSON',
url: process.env.BACKEND_URL + socialRoute + '/facebook',
// data: option,
data: form,
headers: {
'secret': 'its a secret',
'authorization': true
},
contentType: false,
processData: false
}, function(error, response,
console.log('body', body);
return cb(error, body);
});
}
));
(ps 我还想向你们展示注释代码,即选项变量。即使这样也没有用)
后端服务器
路由器
const socialLoginCont = require('../controllers/socialLogin.cont');
router.post('/facebook', socialLoginCont.facebook);
(是的,我正在使用快速路由器)
控制器
const formidable = require('formidable');
const User = require('../models/Users');
const facebook = async (req, res, next) => {
const form = new formidable.IncomingForm();
return form.parse(req, async (err, fields, files) => {
res.send('it works from facebook: '+ fields);
});
}
module.exports = {
facebook
//, and more
}
由于我的后端服务器中的所有其他代码都可以正常工作,所以我没有添加任何附加代码,只是我需要帮助的部分在
我单击 facebook 签名按钮后,我在终端中收到此消息
[nodemon] watching: *.*
[nodemon] starting `node app.js`
Server started on port 8000
body it works facebook: [object object]
[nodemon] restarting due to changes...
[nodemon] restarting due to changes...
[nodemon] starting `node app.js`
我什至使用Postman尝试过,这是输出
it works from facebook[object Object]
如果我输出单个字段,则显示未定义, 即
res.send(fields.socialLogin)
如果我输出多个字段,它显示[object object]
即
res.send(fields)
我猜就是这样,如果你们不明白,我会尝试添加更多代码,但我希望你能明白我想要做的事情的要点
(我也搜索过这种答案,但没有找到)
示例
我想做的是这样的
passport.use(new FacebookStrategy({
clientID: process.env.FACEBOOK_ID,
clientSecret: process.env.FACEBOOK_SECRET,
callbackURL: `${process.env.BASE_URL}/auth/facebook/callback`,
profileFields: ['name', 'email', 'link', 'locale', 'timezone', 'gender'],
passReqToCallback: true
}, (req, accessToken, refreshToken, profile, done) => {
if (req.user) {
User.findOne({ facebook: profile.id }, (err, existingUser) => {
if (err) { return done(err); }
if (existingUser) {
req.flash('errors', { msg: 'There is already a Facebook account that belongs to you. Sign in with that account or delete it, then link it with your current account.' });
done(err);
} else {
User.findById(req.user.id, (err, user) => {
if (err) { return done(err); }
user.facebook = profile.id;
user.tokens.push({ kind: 'facebook', accessToken });
user.profile.name = user.profile.name || `${profile.name.givenName} ${profile.name.familyName}`;
user.profile.gender = user.profile.gender || profile._json.gender;
user.profile.picture = user.profile.picture || `https://graph.facebook.com/${profile.id}/picture?type=large`;
user.save((err) => {
req.flash('info', { msg: 'Facebook account has been linked.' });
done(err, user);
});
});
}
});
} else {
User.findOne({ facebook: profile.id }, (err, existingUser) => {
if (err) { return done(err); }
if (existingUser) {
return done(null, existingUser);
}
User.findOne({ email: profile._json.email }, (err, existingEmailUser) => {
if (err) { return done(err); }
if (existingEmailUser) {
req.flash('errors', { msg: 'There is already an account using this email address. Sign in to that account and link it with Facebook manually from Account Settings.' });
done(err);
} else {
const user = new User();
user.email = profile._json.email;
user.facebook = profile.id;
user.tokens.push({ kind: 'facebook', accessToken });
user.profile.name = `${profile.name.givenName} ${profile.name.familyName}`;
user.profile.gender = profile._json.gender;
user.profile.picture = `https://graph.facebook.com/${profile.id}/picture?type=large`;
user.profile.location = (profile._json.location) ? profile._json.location.name : '';
user.save((err) => {
done(err, user);
});
}
});
});
}
}));
这是来自https://github.com/sahat/hackathon-starter的示例,他们将凭据存储到数据库中(简单)
解决方案
您需要在代码中提及正确的内容类型,例如标题中的 'Content-Type': 'application/x-www-form-urlencoded',目前您正在设置“contentType: false”。还要检查 dataType: 'JSON',如果您不确定返回的内容,请将其删除。请参阅此链接以获取示例 https://flaviocopes.com/node-http-post/
推荐阅读
- ms-office - Office web add-in : Office.initialize() function
- python - 在保持句子结构和标点符号的同时打乱单词的字符
- vivado - AXI 协议,安全和非安全交易的区别
- node.js - 由于 fetch 如何下载存档?节点
- spring-boot - 找不到测试类 - Spring Boot
- typescript - 无法从打字稿文件导入导出的类
- python - 函数调用不执行其定义
- python - 如何避免三元运算符赋值中的重复?
- python - 'str' 和 'int' 的实例之间不支持 '>'
- ui-automation - 桌面应用程序显示“Chrome 旧版窗口” - 无法自动化