gpt4 book ai didi

node.js - axios 上传到 node.js API 导致 aws s3 中的文件变得不可读

转载 作者:太空宇宙 更新时间:2023-11-04 00:08:12 26 4
gpt4 key购买 nike

Screen of Upload
Screen of Download
每当我使用客户端上传面板时,上传到存储桶的文件都会被正确命名,但无法打开。它们的大小也与前端上传的版本略有不同。我想知道我处理缓冲区/读取文件的方式是否有问题,但我昨天才开始使用它们,所以我相当迷失。如果你们中的任何一位天才程序员能够对这个问题提供一些见解,我将永远感激不已!总体目标是能够将文件上传到任何文件类型的 aws s3 存储桶,然后能够下载这些文件,而不会修改这些文件或使其无法打开。

服务器端 JavaScript;

var express = require("express");
var mongodb = require("mongodb");
var _ = require("lodash");
var bodyParser = require("body-parser");
var app = express();
var router = express.Router();
var mongoose = require("mongoose");
var AWS = require('aws-sdk');
AWS.config.update({region: 'us-west-1'});
var s3 = new AWS.S3({apiVersion: '2006-03-01'});

...
...
...

router.post('/upload', function (req, res) {
var file = new File({name: req.body.fileName, type: req.body.contentType, buffer: req.body.file});
var fs = require('fs');
var fileStream = fs.createWriteStream(req.body.fileName);
fileStream.write(req.body.file)
fileStream.end(function () { console.log('done'); });
fileStream.on('error', function(err) {
console.log('File Error', err);
});
fs.readFile(req.body.fileName, (err, data) => {
if (err) throw err;
console.log(data);
const params = {
Bucket: req.body.crystalName,
Key: req.body.fileName,
Body: data
};
s3.upload(params, function(s3Err, data) {
if (s3Err) {
console.log(s3Err);
} else {
res.send(`File uploaded successfully at ${data.Location}`);
console.log(`File uploaded successfully at ${data.Location}`);
}
});
});
});

客户端上传功能(vue.js);

<template>
<div class="main">
<input v-model="crystalName" placeholder="Crystal Name" />
<input type="file" @change="onFileChange"/>
<button v-on:click="uploadToCrystal">Upload</button>
<span>{{this.file}}</span>
</div>
</template>

<script>
import axios from 'axios'
export default {
name: 'crystalviewer',
props: ['user'],
data: function () {
return {
crystalName: '',
fileName: '',
contentType: '',
file: ''
}
},
methods: {
onFileChange (file) {
let vue = this
var reader = new FileReader()
this.fileName = file.target.files[0].name || file.dataTransfer.files[0].name
this.contentType = file.target.files[0].type || file.dataTransfer.files[0].type
console.log(this.contentType)
var start = 0
var stop = file.target.files[0].size
var blob = file.target.files[0].slice(start, stop)
reader.onloadend = function (file) {
vue.file = file.target.result
}
reader.readAsText(blob, 'utf-8')
},
uploadToCrystal () {
let vue = this
axios.post('https://api.mystic-crm.com/crystalviewer/upload', {
crystalName: vue.crystalName,
fileName: vue.fileName,
contentType: vue.contentType,
file: vue.file
})
.then(response => {
console.log(response)
})
.catch(err => {
console.log(err)
})
}
}
}
</script>

<style scoped lang="less">
.main {

}
</style>

要在上传后获取文件,请运行 get 操作;

https://api.mystic-crm.com/crystalviewer/contents/:crystalName/:fileName

哪里;

:crystalName = testcrystalmystic
:fileName = your_file_to_get

最佳答案

事实证明,切换到 Multiparty 是解决方案,现在我可以通过表单上传。显然 axios 不支持文件上传,但表单支持,这是一个有趣的发现。 编辑添加的工作前端

var express = require("express");
var AWS = require('aws-sdk');
AWS.config.update({region: 'us-west-1'});
var s3 = new AWS.S3({apiVersion: '2006-03-01'});
var multiparty = require('multiparty');

router.post('/upload', function (req, res) {
var form = new multiparty.Form();
var destPath;
var crystalName;
form.on('field', function(name, value) {
if (name === 'crystalName') {
crystalName = value
} else if (name === 'fileName') {
destPath = value;
}
});
form.on('part', function(part) {
s3.putObject({
Bucket: crystalName,
Key: destPath,
ACL: 'public-read',
Body: part,
ContentLength: part.byteCount
}, function(err, data) {
if (err) throw err;
console.log("done", data);
res.end("OK");
console.log("https://s3.amazonaws.com/" + crystalName + '/' + destPath);
});
});
form.parse(req);
});

前端前;

<template>
<div class="main">
<form v-on:submit="submit">
<input name="crystalName" placeholder="Crystal Name" />
<input name="fileName" v-model="fileName" placeholder="File Name" v-show="false" />
<input name="file" type="file" @change="onFileChange"/>
<input type="submit" value="Upload File" />
</form>
</div>
</template>

<script>
export default {
name: 'crystalviewer',
props: ['user'],
data: function () {
return {
fileName: '',
modal: ''
}
},
methods: {
submit (event) {
let vue = this
var form = document.forms[0]
var request = new XMLHttpRequest()
request.open('POST', 'https://api.mystic-crm.com/crystalviewer/upload', true)
request.setRequestHeader('accept', 'multipart/form-data')
event.preventDefault()
var formData = new FormData(form)
request.send(formData)
request.onreadystatechange = function () {
if (request.readyState < 4) {
vue.modal = 'loading'
} else if (request.readyState === 4) {
if (request.status === 200 || request.status < 300) {
vue.modal = 'success'
console.log('success')
} else {
vue.modal = 'failure'
console.log('failure')
}
}
}
},
onFileChange (file) {
this.fileName = file.target.files[0].name || file.dataTransfer.files[0].name
}
}
}
</script>

<style scoped lang="less">
.main {

}
</style>

关于node.js - axios 上传到 node.js API 导致 aws s3 中的文件变得不可读,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51200090/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com