Nodejs- 将正文设置为 Google 云任务队列
Nodejs- Set body to Google cloud task queue
我在 Google 应用程序引擎中有一个 nodejs 服务器,我想在其中使用 Google Cloud Task queue.
将长 运行 任务委托给任务队列
任务队列未传送请求正文但到达端点:
这是我将任务添加到任务队列的方式:
// Imports the Google Cloud Tasks library.
const cloudTasks = require('@google-cloud/tasks');
// Instantiates a client.
const client = new cloudTasks.CloudTasksClient();
const project = 'projectname';
const queue = 'queuename';
const location = 'us-central1';
const parent = client.queuePath(project, location, queue);
// Send create task request.
exports.sender = async function (options) {
// Construct the fully qualified queue name.
let myMap = new Map();
myMap.set("Content-Type", "application/json");
const task = {
appEngineHttpRequest: {
httpMethod: 'POST',
relativeUri: '/log_payload',
headers: myMap,
body: options/* Buffer.from(JSON.stringify(options)).toString('base64')*/
},
};
/* if (options.payload !== undefined) {
task.appEngineHttpRequest.body = Buffer.from(options.payload).toString(
'base64'
);
}*/
if (options.inSeconds !== undefined) {
task.scheduleTime = {
seconds: options.inSeconds + Date.now() / 1000,
};
}
const request = {
parent: parent,
task: task,
};
client.createTask(request)
.then(response => {
const task = response[0].name;
//console.log(`Created task ${task}`);
return {'Response': String(response)}
})
.catch(err => {
//console.error(`Error in createTask: ${err.message || err}`);
return `Error in createTask: ${err.message || err}`;
});
};
这是端点接收:
app.post('/log_payload', async (req, res) => {
let mailOptions = {
subject: 'Message Delivered',
from: 'sender@example.com',
to: "receiver@example.com",
text: String(JSON.stringify(JSON.stringify(req.body)))
};
return await mailer.sendEmail(mailOptions).then(value => {
return res.send(`Received task payload: ${value}`).end()
}).catch(reason => {
res.send(`Worker error: ${reason.message}`).end()
});
});
收到邮件后,正文都是空的Json对象。
我做错了什么?
由 this example, I believe the best way to parse the body from the request is to use the body-parser package 指导。
您可以通过更改接收端点文件来实现此目的,包括以下内容:
const bodyParser = require('body-parser');
app.use(bodyParser.raw());
app.use(bodyParser.json());
app.use(bodyParser.text());
app.post('/log_payload', async (req, res) => {
let mailOptions = {
subject: 'Message Delivered',
from: 'sender@example.com',
to: "receiver@example.com",
text: req.body
};
return await mailer.sendEmail(mailOptions).then(value => {
return res.send(`Received task payload: ${value}`).end()
}).catch(reason => {
res.send(`Worker error: ${reason.message}`).end()
});
});
补充@Joan Grau 的回答:
如果添加此过滤器,您可以确保正确解析结果:
var bodyParser = require('body-parser');
var rawBodySaver = function (req, res, buf, encoding) {
if (buf && buf.length) {
req.rawBody = buf.toString(encoding || 'utf8');
}
}
app.use(bodyParser.json({ verify: rawBodySaver }));
app.use(bodyParser.urlencoded({ verify: rawBodySaver, extended: true }));
app.use(bodyParser.raw({ verify: rawBodySaver, type: function () { return true } }));
(想法取自 this post)
特别是,一个好的做法是只在需要的地方应用解析器。而且,除此之外,考虑将正文内容作为 base64 字符串发送(云任务需要这样做才能工作)。用所有这些重写你的代码:
const task = {
appEngineHttpRequest: {
httpMethod: 'POST',
relativeUri: '/log_payload',
headers: myMap,
body: Buffer.from(JSON.stringify(options)).toString('base64')
},
};
和端点:
var bodyParser = require('body-parser');
var rawBodySaver = function (req, res, buf, encoding) {
if (buf && buf.length) {
req.rawBody = buf.toString(encoding || 'utf8');
}
}
app.use('/log_payload', bodyParser.json({ verify: rawBodySaver }));
app.use('/log_payload', bodyParser.urlencoded({ verify: rawBodySaver, extended: true }));
app.use('/log_payload', bodyParser.raw({ verify: rawBodySaver, type: function () { return true } }));
app.post('/log_payload', async (req, res) => {
let mailOptions = {
subject: 'Message Delivered',
from: 'sender@example.com',
to: "receiver@example.com",
text: req.body //no need to parse here!
};
return await mailer.sendEmail(mailOptions).then(value => {
return res.send(`Received task payload: ${value}`).end()
}).catch(reason => {
res.send(`Worker error: ${reason.message}`).end()
});
});
我在 Google 应用程序引擎中有一个 nodejs 服务器,我想在其中使用 Google Cloud Task queue.
将长 运行 任务委托给任务队列任务队列未传送请求正文但到达端点:
这是我将任务添加到任务队列的方式:
// Imports the Google Cloud Tasks library.
const cloudTasks = require('@google-cloud/tasks');
// Instantiates a client.
const client = new cloudTasks.CloudTasksClient();
const project = 'projectname';
const queue = 'queuename';
const location = 'us-central1';
const parent = client.queuePath(project, location, queue);
// Send create task request.
exports.sender = async function (options) {
// Construct the fully qualified queue name.
let myMap = new Map();
myMap.set("Content-Type", "application/json");
const task = {
appEngineHttpRequest: {
httpMethod: 'POST',
relativeUri: '/log_payload',
headers: myMap,
body: options/* Buffer.from(JSON.stringify(options)).toString('base64')*/
},
};
/* if (options.payload !== undefined) {
task.appEngineHttpRequest.body = Buffer.from(options.payload).toString(
'base64'
);
}*/
if (options.inSeconds !== undefined) {
task.scheduleTime = {
seconds: options.inSeconds + Date.now() / 1000,
};
}
const request = {
parent: parent,
task: task,
};
client.createTask(request)
.then(response => {
const task = response[0].name;
//console.log(`Created task ${task}`);
return {'Response': String(response)}
})
.catch(err => {
//console.error(`Error in createTask: ${err.message || err}`);
return `Error in createTask: ${err.message || err}`;
});
};
这是端点接收:
app.post('/log_payload', async (req, res) => {
let mailOptions = {
subject: 'Message Delivered',
from: 'sender@example.com',
to: "receiver@example.com",
text: String(JSON.stringify(JSON.stringify(req.body)))
};
return await mailer.sendEmail(mailOptions).then(value => {
return res.send(`Received task payload: ${value}`).end()
}).catch(reason => {
res.send(`Worker error: ${reason.message}`).end()
});
});
收到邮件后,正文都是空的Json对象。 我做错了什么?
由 this example, I believe the best way to parse the body from the request is to use the body-parser package 指导。
您可以通过更改接收端点文件来实现此目的,包括以下内容:
const bodyParser = require('body-parser');
app.use(bodyParser.raw());
app.use(bodyParser.json());
app.use(bodyParser.text());
app.post('/log_payload', async (req, res) => {
let mailOptions = {
subject: 'Message Delivered',
from: 'sender@example.com',
to: "receiver@example.com",
text: req.body
};
return await mailer.sendEmail(mailOptions).then(value => {
return res.send(`Received task payload: ${value}`).end()
}).catch(reason => {
res.send(`Worker error: ${reason.message}`).end()
});
});
补充@Joan Grau 的回答:
如果添加此过滤器,您可以确保正确解析结果:
var bodyParser = require('body-parser');
var rawBodySaver = function (req, res, buf, encoding) {
if (buf && buf.length) {
req.rawBody = buf.toString(encoding || 'utf8');
}
}
app.use(bodyParser.json({ verify: rawBodySaver }));
app.use(bodyParser.urlencoded({ verify: rawBodySaver, extended: true }));
app.use(bodyParser.raw({ verify: rawBodySaver, type: function () { return true } }));
(想法取自 this post)
特别是,一个好的做法是只在需要的地方应用解析器。而且,除此之外,考虑将正文内容作为 base64 字符串发送(云任务需要这样做才能工作)。用所有这些重写你的代码:
const task = {
appEngineHttpRequest: {
httpMethod: 'POST',
relativeUri: '/log_payload',
headers: myMap,
body: Buffer.from(JSON.stringify(options)).toString('base64')
},
};
和端点:
var bodyParser = require('body-parser');
var rawBodySaver = function (req, res, buf, encoding) {
if (buf && buf.length) {
req.rawBody = buf.toString(encoding || 'utf8');
}
}
app.use('/log_payload', bodyParser.json({ verify: rawBodySaver }));
app.use('/log_payload', bodyParser.urlencoded({ verify: rawBodySaver, extended: true }));
app.use('/log_payload', bodyParser.raw({ verify: rawBodySaver, type: function () { return true } }));
app.post('/log_payload', async (req, res) => {
let mailOptions = {
subject: 'Message Delivered',
from: 'sender@example.com',
to: "receiver@example.com",
text: req.body //no need to parse here!
};
return await mailer.sendEmail(mailOptions).then(value => {
return res.send(`Received task payload: ${value}`).end()
}).catch(reason => {
res.send(`Worker error: ${reason.message}`).end()
});
});