anm*_*wal 8 google-cloud-functions
我已经阅读了有关如何将图像上传到存储桶并通过后台功能进行后期处理的教程.但我的要求是上传图像,进行后处理并通过HTTP函数立即返回结果.如果这是正确的做法,请告诉我,因为我没有在网上获得太多的资料.我是这样做的:
HTTP云功能:
exports.uploadImage = function (req, res){
var file = req.body.file;
uploadSomewhere(file)(); < post-processing code which is working fine >
Run Code Online (Sandbox Code Playgroud)
UI表格:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.js"></script>
<script src="http://malsup.github.com/jquery.form.js"></script>
<form id="myForm" action="<cloud_function_url>/uploadImage" method="post">
<label for="file">Choose file to upload</label>
<input type="file" id="file" name="file" multiple>
<input type="submit" value="Submit" />
</form>
<script>
$(document).ready(function() {
$('#myForm').ajaxForm(function() {
});
});
</script>
Run Code Online (Sandbox Code Playgroud)
问题是,在我部署该功能后,当我从存在功能的文件夹上传图像时,图像被上传.但是,如果我从任何其他位置上传图像,它会返回错误:
错误:上传图像文件时出错.... - 错误:ENOENT:没有这样的文件或目录,打开'....'
请告诉我我做错了什么或者您是否需要更多信息.
这里有用于将文件直接上传到 Cloud Functions 的示例代码: https: //cloud.google.com/functions/docs/writing/http#multipart_data_and_file_uploads,但请注意,使用此方法时有文件大小限制 (10MB)。如果您的文件大于此大小,我建议您使用云存储方法并使用Firebase 实时数据库之类的工具来管理客户端上的状态。
因此,您使用 Cloud Function 生成签名的上传 URL,然后使用 RTDB 跟踪客户端的进度。返回 URL和对数据库中要跟踪进度的位置的引用。客户端将监视该位置以获取更新。然后客户端将文件上传到云存储并触发第二个函数。后处理后,它会更新 RTDB,并将更新推送到客户端。从客户端的角度来看,这都是同步的,但它实际上是数据库中状态合并的一系列异步操作。
如果您同意文件大小 < 10MB,这里是从文档中获取的内联更新示例代码:
/**
* Parses a 'multipart/form-data' upload request
*
* @param {Object} req Cloud Function request context.
* @param {Object} res Cloud Function response context.
*/
const path = require('path');
const os = require('os');
const fs = require('fs');
// Node.js doesn't have a built-in multipart/form-data parsing library.
// Instead, we can use the 'busboy' library from NPM to parse these requests.
const Busboy = require('busboy');
exports.uploadFile = (req, res) => {
if (req.method === 'POST') {
const busboy = new Busboy({ headers: req.headers });
const tmpdir = os.tmpdir();
// This object will accumulate all the fields, keyed by their name
const fields = {};
// This object will accumulate all the uploaded files, keyed by their name.
const uploads = {};
// This code will process each non-file field in the form.
busboy.on('field', (fieldname, val) => {
// TODO(developer): Process submitted field values here
console.log(`Processed field ${fieldname}: ${val}.`);
fields[fieldname] = val;
});
let fileWrites = [];
// This code will process each file uploaded.
busboy.on('file', (fieldname, file, filename) => {
// Note: os.tmpdir() points to an in-memory file system on GCF
// Thus, any files in it must fit in the instance's memory.
console.log(`Processed file ${filename}`);
const filepath = path.join(tmpdir, filename);
uploads[fieldname] = filepath;
const writeStream = fs.createWriteStream(filepath);
file.pipe(writeStream);
// File was processed by Busboy; wait for it to be written to disk.
const promise = new Promise((resolve, reject) => {
file.on('end', () => {
writeStream.end();
});
writeStream.on('finish', resolve);
writeStream.on('error', reject);
});
fileWrites.push(promise);
});
// Triggered once all uploaded files are processed by Busboy.
// We still need to wait for the disk writes (saves) to complete.
busboy.on('finish', () => {
Promise.all(fileWrites)
.then(() => {
// TODO(developer): Process saved files here
for (const name in uploads) {
const file = uploads[name];
fs.unlinkSync(file);
}
res.send();
});
});
busboy.end(req.rawBody);
} else {
// Return a "method not allowed" error
res.status(405).end();
}
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3380 次 |
| 最近记录: |