如何使用axios上传文件到Dropbox
How to upload file to Dropbox with axios
我需要使用 axios
将文件上传到 Dropbox。这是我的代码:
const uploadToExternalService = async function uploadToExternalService(token, content) {
try {
let res = await axios({
url: 'https://api-content.dropbox.com/1/files_put/auto/'+'file_name',
method: 'put',
// timeout: 8000,
headers: {
Authorization: 'Bearer ' + token,
'Content-Type': 'text/plain',
body: content
}
})
if(res.status == 200){
// test for status you want, etc
console.log(res.status)
}
if(res.status == 400){
console.log(res)
}
return res.data
}
catch (err) {
console.error(err);
}
}
uploadToExternalService(SECRET_KEY, req.file).then(res => console.log(res));
我遇到错误请求失败,状态代码为 400
您使用的是正式停用的 dropbox v1 API。为什么不使用 v2?
对于您的问题,请尝试将正文发送到 headers
之外
headers: {
Authorization: 'Bearer ' + token,
'Content-Type': 'text/plain'
},
body: content
更正代码:
const uploadToExternalService = async function uploadToExternalService(token, content) {
try {
let res = await axios({
url: 'https://api-content.dropbox.com/1/files_put/auto/'+'file_name',
method: 'put',
// timeout: 8000,
headers: {
Authorization: 'Bearer ' + token,
'Content-Type': 'text/plain'
},
body: content
})
if(res.status == 200){
// test for status you want, etc
console.log(res.status)
}
if(res.status == 400){
console.log(res)
}
return res.data
}
catch (err) {
console.error(err);
}
}
uploadToExternalService(SECRET_KEY, req.file).then(res => console.log(res));
最终我设法使用 dropbox-v2-api
找到了解决方案。希望这个答案能为其他社区成员提供一个有用的代码示例,尽管该解决方案已实施 w/o axios
import dropboxV2Api from "dropbox-v2-api";
import fs from "fs";
// authentication
const dropbox = dropboxV2Api.authenticate({
token: DROPBOX_SECRET_KEY
});
//configuring parameters
const params = Object.freeze({
resource: 'files/upload',
parameters: {
path: '/file_name.docx'
},
readStream: fs.createReadStream(filePath)
// filePath: path to the local file that we want to upload to Dropbox
});
let dropboxPromise = new Promise(function(resolve, reject) {
dropbox(params, function(err, result) {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
await dropboxPromise.then(function (resultObj) {
console.log("fileUpload_OK")
}).catch(function(err){
console.log(err.message)
});
问题
Dropbox 文档中的示例 cURL 是:
curl -X POST https://content.dropboxapi.com/2/files/upload \
--header "Authorization: Bearer " \
--header "Dropbox-API-Arg: {\"path\": \"/Homework/math/Matrices.txt\",\"mode\": \"add\",\"autorename\": true,\"mute\": false,\"strict_conflict\": false}" \
--header "Content-Type: application/octet-stream" \
--data-binary @local_file.txt
--data-binary
表示 /upload
端点要求文件作为二进制数据发送。在axios中,好像是the only way to do this is with the FormData()
interface.
但是,使用 FormData()
界面需要使用 Content-Type: multipart/form-data
。 /upload
端点需要 Content-Type: application/octet-stream
.
因此,我认为在这种情况下无法使用 Axios 上传。
替代解决方案
dropbox-v2-api
不是 Dropbox 的官方 API,对于上传超过 150MB 的文件,我找不到任何解释。因此,我会使用 dropbox-sdk-js
。 example they give for /upload
是:
function uploadFile() {
const UPLOAD_FILE_SIZE_LIMIT = 150 * 1024 * 1024;
var ACCESS_TOKEN = document.getElementById('access-token').value;
var dbx = new Dropbox.Dropbox({ accessToken: ACCESS_TOKEN });
var fileInput = document.getElementById('file-upload');
var file = fileInput.files[0];
if (file.size < UPLOAD_FILE_SIZE_LIMIT) { // File is smaller than 150 Mb - use filesUpload API
dbx.filesUpload({path: '/' + file.name, contents: file})
.then(function(response) {
var results = document.getElementById('results');
var br = document.createElement("br");
results.appendChild(document.createTextNode('File uploaded!'));
results.appendChild(br);
console.log(response);
})
.catch(function(error) {
console.error(error);
});
} else { // File is bigger than 150 Mb - use filesUploadSession* API
const maxBlob = 8 * 1000 * 1000; // 8Mb - Dropbox JavaScript API suggested max file / chunk size
var workItems = [];
var offset = 0;
while (offset < file.size) {
var chunkSize = Math.min(maxBlob, file.size - offset);
workItems.push(file.slice(offset, offset + chunkSize));
offset += chunkSize;
}
const task = workItems.reduce((acc, blob, idx, items) => {
if (idx == 0) {
// Starting multipart upload of file
return acc.then(function() {
return dbx.filesUploadSessionStart({ close: false, contents: blob})
.then(response => response.session_id)
});
} else if (idx < items.length-1) {
// Append part to the upload session
return acc.then(function(sessionId) {
var cursor = { session_id: sessionId, offset: idx * maxBlob };
return dbx.filesUploadSessionAppendV2({ cursor: cursor, close: false, contents: blob }).then(() => sessionId);
});
} else {
// Last chunk of data, close session
return acc.then(function(sessionId) {
var cursor = { session_id: sessionId, offset: file.size - blob.size };
var commit = { path: '/' + file.name, mode: 'add', autorename: true, mute: false };
return dbx.filesUploadSessionFinish({ cursor: cursor, commit: commit, contents: blob });
});
}
}, Promise.resolve());
task.then(function(result) {
var results = document.getElementById('results');
results.appendChild(document.createTextNode('File uploaded!'));
}).catch(function(error) {
console.error(error);
});
}
return false;
}
我需要使用 axios
将文件上传到 Dropbox。这是我的代码:
const uploadToExternalService = async function uploadToExternalService(token, content) {
try {
let res = await axios({
url: 'https://api-content.dropbox.com/1/files_put/auto/'+'file_name',
method: 'put',
// timeout: 8000,
headers: {
Authorization: 'Bearer ' + token,
'Content-Type': 'text/plain',
body: content
}
})
if(res.status == 200){
// test for status you want, etc
console.log(res.status)
}
if(res.status == 400){
console.log(res)
}
return res.data
}
catch (err) {
console.error(err);
}
}
uploadToExternalService(SECRET_KEY, req.file).then(res => console.log(res));
我遇到错误请求失败,状态代码为 400
您使用的是正式停用的 dropbox v1 API。为什么不使用 v2?
对于您的问题,请尝试将正文发送到 headers
headers: {
Authorization: 'Bearer ' + token,
'Content-Type': 'text/plain'
},
body: content
更正代码:
const uploadToExternalService = async function uploadToExternalService(token, content) {
try {
let res = await axios({
url: 'https://api-content.dropbox.com/1/files_put/auto/'+'file_name',
method: 'put',
// timeout: 8000,
headers: {
Authorization: 'Bearer ' + token,
'Content-Type': 'text/plain'
},
body: content
})
if(res.status == 200){
// test for status you want, etc
console.log(res.status)
}
if(res.status == 400){
console.log(res)
}
return res.data
}
catch (err) {
console.error(err);
}
}
uploadToExternalService(SECRET_KEY, req.file).then(res => console.log(res));
最终我设法使用 dropbox-v2-api
找到了解决方案。希望这个答案能为其他社区成员提供一个有用的代码示例,尽管该解决方案已实施 w/o axios
import dropboxV2Api from "dropbox-v2-api";
import fs from "fs";
// authentication
const dropbox = dropboxV2Api.authenticate({
token: DROPBOX_SECRET_KEY
});
//configuring parameters
const params = Object.freeze({
resource: 'files/upload',
parameters: {
path: '/file_name.docx'
},
readStream: fs.createReadStream(filePath)
// filePath: path to the local file that we want to upload to Dropbox
});
let dropboxPromise = new Promise(function(resolve, reject) {
dropbox(params, function(err, result) {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
await dropboxPromise.then(function (resultObj) {
console.log("fileUpload_OK")
}).catch(function(err){
console.log(err.message)
});
问题
Dropbox 文档中的示例 cURL 是:
curl -X POST https://content.dropboxapi.com/2/files/upload \
--header "Authorization: Bearer " \
--header "Dropbox-API-Arg: {\"path\": \"/Homework/math/Matrices.txt\",\"mode\": \"add\",\"autorename\": true,\"mute\": false,\"strict_conflict\": false}" \
--header "Content-Type: application/octet-stream" \
--data-binary @local_file.txt
--data-binary
表示 /upload
端点要求文件作为二进制数据发送。在axios中,好像是the only way to do this is with the FormData()
interface.
但是,使用 FormData()
界面需要使用 Content-Type: multipart/form-data
。 /upload
端点需要 Content-Type: application/octet-stream
.
因此,我认为在这种情况下无法使用 Axios 上传。
替代解决方案
dropbox-v2-api
不是 Dropbox 的官方 API,对于上传超过 150MB 的文件,我找不到任何解释。因此,我会使用 dropbox-sdk-js
。 example they give for /upload
是:
function uploadFile() {
const UPLOAD_FILE_SIZE_LIMIT = 150 * 1024 * 1024;
var ACCESS_TOKEN = document.getElementById('access-token').value;
var dbx = new Dropbox.Dropbox({ accessToken: ACCESS_TOKEN });
var fileInput = document.getElementById('file-upload');
var file = fileInput.files[0];
if (file.size < UPLOAD_FILE_SIZE_LIMIT) { // File is smaller than 150 Mb - use filesUpload API
dbx.filesUpload({path: '/' + file.name, contents: file})
.then(function(response) {
var results = document.getElementById('results');
var br = document.createElement("br");
results.appendChild(document.createTextNode('File uploaded!'));
results.appendChild(br);
console.log(response);
})
.catch(function(error) {
console.error(error);
});
} else { // File is bigger than 150 Mb - use filesUploadSession* API
const maxBlob = 8 * 1000 * 1000; // 8Mb - Dropbox JavaScript API suggested max file / chunk size
var workItems = [];
var offset = 0;
while (offset < file.size) {
var chunkSize = Math.min(maxBlob, file.size - offset);
workItems.push(file.slice(offset, offset + chunkSize));
offset += chunkSize;
}
const task = workItems.reduce((acc, blob, idx, items) => {
if (idx == 0) {
// Starting multipart upload of file
return acc.then(function() {
return dbx.filesUploadSessionStart({ close: false, contents: blob})
.then(response => response.session_id)
});
} else if (idx < items.length-1) {
// Append part to the upload session
return acc.then(function(sessionId) {
var cursor = { session_id: sessionId, offset: idx * maxBlob };
return dbx.filesUploadSessionAppendV2({ cursor: cursor, close: false, contents: blob }).then(() => sessionId);
});
} else {
// Last chunk of data, close session
return acc.then(function(sessionId) {
var cursor = { session_id: sessionId, offset: file.size - blob.size };
var commit = { path: '/' + file.name, mode: 'add', autorename: true, mute: false };
return dbx.filesUploadSessionFinish({ cursor: cursor, commit: commit, contents: blob });
});
}
}, Promise.resolve());
task.then(function(result) {
var results = document.getElementById('results');
results.appendChild(document.createTextNode('File uploaded!'));
}).catch(function(error) {
console.error(error);
});
}
return false;
}