从 URL 加载图像并上传到 Strapi 中的媒体库
Load image from URL and upload to media library in Strapi
我正在为我的 Strapi 应用程序构建一个 CSV 导入器,它的任务之一是从单元格中读取图像 URL 并从 URL 下载它并将其保存到媒体库.
代码如下所示:
const request = require('request').defaults({ encoding: null });
request.get(src, function (err, res, body) {
const fileName = src.split('/').pop();
strapi.plugins.upload.services.upload.upload({
files: {
path: body,
name: fileName,
type: res.headers['content-type'],
size: Number(res.headers['content-length']),
},
data: {
ref: 'products',
refId: data.itemID,
field: 'images'
}
});
});
下载成功,我在 request.get
回调的 body
变量中获得了一个缓冲区。但是将其传递给 strapi.plugins.upload.services.upload.upload
会出现以下错误:
UnhandledPromiseRejectionWarning: TypeError [ERR_INVALID_ARG_VALUE]: The argument 'path' must be a string or Uint8Array without null bytes. Received <Buffer ff d8 ff e1 10 c1 45 78 69 66 00 00 49 49 2a 00 08 00 00 00 0f 00 00 01 03 00 01 00 00 00 6c 05 00 00 01 01 03 00 01 00 ...
我已经尝试用 path: new Uint8Array(body),
替换 path: body,
但没有成功。
知道我做错了什么吗?
感谢您的帮助!
我在我的一个项目中有完全相同的要求,我必须从 URL
中获取文件,然后将其上传到媒体库。我通过首先从 URL
中获取字节流然后将其保存到 tmp
文件夹中的文件来解决这个问题。文件完全下载后,我只是使用 strapi
的内置 upload
方法将文件上传到媒体库。
您需要安装的库
$ npm install mime-types
$ npm install axios
$ npm install lodash
实施
// my-project/helpers/uploader.js
const _ = require('lodash');
const axios = require('axios').default;
const fs = require('fs');
const stream = require('stream');
const path = require('path');
const promisify = require('util').promisify;
const mime = require('mime-types');
module.exports = {
getFileDetails(filePath) {
return new Promise((resolve, reject) => {
fs.stat(filePath, (err, stats) => {
if (err) reject(err.message);
resolve(stats);
});
});
},
deleteFile(filePath) {
return new Promise((resolve, reject) => {
fs.unlink(filePath, (err) => {
if (err) reject(err.message);
resolve('deleted');
});
});
},
async uploadToLibrary(imageByteStreamURL) {
const filePath = './tmp/myImage.jpeg';
const { data } = await axios.get(imageByteStreamURL, {
responseType: 'stream',
});
const file = fs.createWriteStream(filePath);
const finished = promisify(stream.finished);
data.pipe(file);
await finished(file);
const image = await this.upload(filePath, 'uploads');
return image;
},
async upload(filePath, saveAs) {
const stats = await this.getFileDetails(filePath);
const fileName = path.parse(filePath).base;
const res = await strapi.plugins.upload.services.upload.upload({
data: { path: saveAs },
files: {
path: filePath,
name: fileName,
type: mime.lookup(filePath),
size: stats.size,
},
});
await this.deleteFile(filePath);
return _.first(res);
},
};
那么在你真正的 service/controller 中,你可以像这样简单地从你的助手调用方法:
const uploader = require('../../../helpers/uploader');
const img = await uploader.uploadToLibrary('http://www.example.com/demo-image.jpg');
console.log(img);
参考文献:
我正在为我的 Strapi 应用程序构建一个 CSV 导入器,它的任务之一是从单元格中读取图像 URL 并从 URL 下载它并将其保存到媒体库.
代码如下所示:
const request = require('request').defaults({ encoding: null });
request.get(src, function (err, res, body) {
const fileName = src.split('/').pop();
strapi.plugins.upload.services.upload.upload({
files: {
path: body,
name: fileName,
type: res.headers['content-type'],
size: Number(res.headers['content-length']),
},
data: {
ref: 'products',
refId: data.itemID,
field: 'images'
}
});
});
下载成功,我在 request.get
回调的 body
变量中获得了一个缓冲区。但是将其传递给 strapi.plugins.upload.services.upload.upload
会出现以下错误:
UnhandledPromiseRejectionWarning: TypeError [ERR_INVALID_ARG_VALUE]: The argument 'path' must be a string or Uint8Array without null bytes. Received <Buffer ff d8 ff e1 10 c1 45 78 69 66 00 00 49 49 2a 00 08 00 00 00 0f 00 00 01 03 00 01 00 00 00 6c 05 00 00 01 01 03 00 01 00 ...
我已经尝试用 path: new Uint8Array(body),
替换 path: body,
但没有成功。
知道我做错了什么吗?
感谢您的帮助!
我在我的一个项目中有完全相同的要求,我必须从 URL
中获取文件,然后将其上传到媒体库。我通过首先从 URL
中获取字节流然后将其保存到 tmp
文件夹中的文件来解决这个问题。文件完全下载后,我只是使用 strapi
的内置 upload
方法将文件上传到媒体库。
您需要安装的库
$ npm install mime-types
$ npm install axios
$ npm install lodash
实施
// my-project/helpers/uploader.js
const _ = require('lodash');
const axios = require('axios').default;
const fs = require('fs');
const stream = require('stream');
const path = require('path');
const promisify = require('util').promisify;
const mime = require('mime-types');
module.exports = {
getFileDetails(filePath) {
return new Promise((resolve, reject) => {
fs.stat(filePath, (err, stats) => {
if (err) reject(err.message);
resolve(stats);
});
});
},
deleteFile(filePath) {
return new Promise((resolve, reject) => {
fs.unlink(filePath, (err) => {
if (err) reject(err.message);
resolve('deleted');
});
});
},
async uploadToLibrary(imageByteStreamURL) {
const filePath = './tmp/myImage.jpeg';
const { data } = await axios.get(imageByteStreamURL, {
responseType: 'stream',
});
const file = fs.createWriteStream(filePath);
const finished = promisify(stream.finished);
data.pipe(file);
await finished(file);
const image = await this.upload(filePath, 'uploads');
return image;
},
async upload(filePath, saveAs) {
const stats = await this.getFileDetails(filePath);
const fileName = path.parse(filePath).base;
const res = await strapi.plugins.upload.services.upload.upload({
data: { path: saveAs },
files: {
path: filePath,
name: fileName,
type: mime.lookup(filePath),
size: stats.size,
},
});
await this.deleteFile(filePath);
return _.first(res);
},
};
那么在你真正的 service/controller 中,你可以像这样简单地从你的助手调用方法:
const uploader = require('../../../helpers/uploader');
const img = await uploader.uploadToLibrary('http://www.example.com/demo-image.jpg');
console.log(img);