我在尝试使用 Node.js 将文件上传到 Crowdin Storage 时遇到问题。问题来了:
描述:当尝试将文件上传到 Crowdin Storage 时,我收到状态代码 400 的错误响应。
错误信息:
{
"errors": [
{
"error": {
"key": "fileStream",
"errors": [
{
"code": "streamIsEmpty",
"message": "Stream size is null. Not empty content expected"
}
]
}
}
]
}
方法:
我正在使用 Axios 发出 HTTP 请求。 我在上传之前已验证该文件存在且不为空。 我已按照 Crowdin API 文档的要求设置了必要的标头(Authorization、Crowdin-API-FileName、Content-Type)。 我正在使用正确的密钥将文件附加到 FormData。
代码片段:
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');
const path = require('path');
// Replace with your actual Crowdin API key and project ID
const CROWDIN_API_KEY = 'crowdin_api_key';
const CROWDIN_PROJECT_ID = 123467890;
// Function to upload file to Crowdin storage
const uploadFileToStorage = async (filePath) => {
try {
const fileName = path.basename(filePath);
// Check if file exists and is not empty
if (!fs.existsSync(filePath)) {
throw new Error(`File does not exist: ${filePath}`);
}
const stats = fs.statSync(filePath);
if (stats.size === 0) {
throw new Error(`File is empty: ${filePath}`);
}
const form = new FormData();
const fileStream = fs.createReadStream(filePath);
form.append('file', fileStream);
console.log('Uploading file to Crowdin:', fileName);
const response = await axios.post('https://api.crowdin.com/api/v2/storages', form, {
headers: {
'Authorization': `Bearer ${CROWDIN_API_KEY}`,
'Crowdin-API-FileName': fileName,
...form.getHeaders()
}
});
return response.data.data.id;
} catch (error) {
console.error('Error uploading file to storage:', error.response ? error.response.data : error.message);
if (error.response) {
console.error('Response status:', error.response.status);
console.error('Response data:', JSON.stringify(error.response.data, null, 2));
}
throw error;
}
};
// Function to add file to Crowdin project
const addFileToProject = async (storageId, fileName) => {
try {
const response = await axios.post(`https://api.crowdin.com/api/v2/projects/${CROWDIN_PROJECT_ID}/files`, {
storageId: storageId,
name: fileName
}, {
headers: {
'Authorization': `Bearer ${CROWDIN_API_KEY}`,
'Content-Type': 'application/json'
}
});
console.log('File added to project successfully:', response.data);
} catch (error) {
console.error('Error adding file to project:', error.response ? error.response.data : error.message);
if (error.response) {
console.error('Response status:', error.response.status);
console.error('Response data:', JSON.stringify(error.response.data, null, 2));
}
throw error;
}
};
// Main function to upload file to Crowdin
const uploadFileToCrowdin = async (filePath) => {
try {
const storageId = await uploadFileToStorage(filePath);
const fileName = path.basename(filePath);
await addFileToProject(storageId, fileName);
} catch (error) {
console.error('Error processing the file:', error.message);
}
};
// Get the file path from command line arguments and call the upload function
const filePath = process.argv[2];
if (!filePath) {
console.error('Please provide the file path as an argument.');
process.exit(1);
}
uploadFileToCrowdin(filePath);
附加信息:
我能够使用提供的 API 密钥成功通过 Crowdin API 进行身份验证。 我已经使用 Postman 测试了 Crowdin API 端点,它们似乎工作正常。 我不确定为什么会遇到这个错误。任何有关如何解决此问题的见解或建议将不胜感激。谢谢!
Crowdin 提供官方 JS API 客户端。我强烈建议使用此客户端以避免必须“手动”完成所有操作。 API 客户端已经封装了与读取文件、构建请求和解析响应相关的所有内容。它还提供了一些额外的辅助功能。
例如:
const crowdin = require('@crowdin/crowdin-api-client');
// initialization of crowdin client
const {
uploadStorageApi,
sourceFilesApi
} = new crowdin.default({
token: 'personalAccessToken',
organization: 'organizationName' // optional
});
async function createFile() {
const projectId = 123;
const fileData = "content"; // your file content
const storage = await uploadStorageApi.addStorage('file1.json', fileData);
const file = await sourceFilesApi.createFile(projectId, {
name: 'file1.json',
title: 'Sample file',
storageId: storage.data.id,
type: 'json'
});
console.log(file);
}
参考资料: