我正在尝试使用Node后端将图像文件上传到Heroku,我可以使它工作,同样的过程在Localhost测试中工作得很好但是在将我的项目部署到Heroku并测试之后,过程中出现了错误并且文件不会上传
BACKEND:
let storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploads')
},
filename: function (req, file, cb) {
cb(null, file.originalname)
}
})
const upload = multer({storage: storage})
router.post('/', upload.single('carImage') ,(req, res) => {
console.log(req.file);
let todayArr = today.slice(0, 4);
})
FRONT:
uploadImageToServer = (imagePath, fileName) => {
const photo = {
fieldname:'carImage',
uri: imagePath,
name: fileName,
type: 'image/jpeg',
};
const data = new FormData();
data.append('carImage', photo);
const config = {
method: 'POST',
body: data,
};
return fetch("https://foo.herokuapp.com/uploadcarimage", config);
}
this.uploadImageToServer(this.state.path, `${this.state.car.plate.toString()}-${date.join('-')}.jpg`)
.then(resp => resp.json())
.then(json => console.log(json))
.catch(err => console.log(err))
服务器错误:
POST /uploadcarimage 500 2172.411 ms - 229
2018-05-28T11:39:53.045824+00:00 heroku[router]: at=info method=GET path="/6866866-Mon-May-28-2018.jpg" host=pure-journey-53428.herokuapp.com request_id=d6f6dfff-af19-4a6f-8f76-a0f14e3f812e fwd="12.34.567.890" dyno=web.1 connect=0ms service=2ms status=404 bytes=368 protocol=https
注意:
仅使用return fetch("http://localhost:3000/uploadcarimage", config);
它运作得很好。
答案 0 :(得分:4)
如果您上载的代码是 images文件夹为空,则不会在Heroku服务器中创建images文件夹。 我已经解决了这个问题,只需在图像文件夹中添加一个图像或任何文件来上传代码即可。现在一切正常:)
注意:如果该文件夹不存在,则无法创建文件夹,因此您需要先创建它。
答案 1 :(得分:1)
我也遇到了同样的问题,即在Localhost测试中相同的过程也可以正常工作,但是将我的项目部署到Heroku并对其进行测试后显示 错误由于CORS策略阻止了对XMLHttpRequest .....的访问:不允许请求头文件x-auth-token',但是我添加了CORS
因此,当在后端终端中命中(heroku logs -t)时,表明“没有这样的文件或目录,请打开”
您的代码没有问题,问题在于对文件系统的任何更改都将持续到dyno关闭或重新启动,这意味着您的映像已成功上传,但是当dyno关闭或重新启动时,Heroku从最近部署。 read
存储数据HEROKU建议使用数据库插件(例如Postgres(用于数据)或专用文件存储服务,例如AWS S3(用于静态文件)
我使用cloudinary + multer上传图像
答案 2 :(得分:1)
我不知道为什么您上传的文件没有被暂时保存。 但这不会长期有效。
每次 dynos 重新启动(当您更改链接的 Github 存储库中的某些代码时也会发生这种情况)或您重新部署应用时,上传文件夹变空(就像在您的 Github 存储库中一样)。
Heroku 建议将上传的内容存储在 Amazon S3 或类似 Microsoft Azure 的东西上。这是一个 guide,专门用于使用 Node.js。
在 S3 上存储文件后,您可以使用适当的库检索它们,具体取决于您配置存储桶的方式。
获取有关如何使用 Amazon s3 here 的完整代码。
答案 3 :(得分:0)
我不确定,但是可能您需要按以下方式设置目的地:
const path = require('path');
destination: function (req, file, cb) {
cb(null, path.resolve(__dirname, 'build'))
}
就我而言,它可以解决问题。
还请记住,如果multer不存在,则无法创建文件夹,因此您需要首先创建它,或者如果您部署应用f.e。到上面设置的heroku目的地可以提供帮助。
无论如何,您都可以在下面使用我的代码(在节点服务器上)-它可以正常工作:
const multer = require('multer');
const path = require('path');
if (process.env.NODE_ENV === 'production') {
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, path.resolve(__dirname, 'build'))
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '_' + Date.now() + '_' + file.originalname)
}
})
} else {
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, path.resolve(__dirname, 'uploads'))
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '_' + Date.now() + '_' + file.originalname)
}
})
}
const uploads = multer({ storage: storage });
app.use(uploads.any());
if (process.env.NODE_ENV === 'production') {
app.use(express.static(path.resolve(__dirname, 'build')));
} else {
app.use(express.static('./public'));
}
//if you need to download (after upload) files in cloudinary
const cloudinary = require('cloudinary');
cloudinary.config({
cloud_name: '...',
api_key: '...',
api_secret: '...'
});
//if you need to del files after upload
const fs = require('fs');
router.post('/admin/create-product-images', (req, res, next) => {
let urls = [];
async function sendImagesToCloudinary() {
for (let file of req.files) {
await cloudinary.uploader.upload(
file.path,
{
public_id: `${Date.now()}`,
resource_type: 'auto'
}
).then(result => {
//del files after upload on cloudinary
fs.unlink(file.path, function (err) {
if (err) {
console.log(err);
}
});
urls.push(result.url);
})
.catch(err => {
console.log(err);
});
}
res.json(urls);
}
sendImagesToCloudinary();
});
答案 4 :(得分:0)
您的代码没有问题,问题在于对文件系统的任何更改都将持续到dyno关闭或重新启动,这意味着您的映像已成功上传,但是当dyno关闭或重新启动时,Heroku从最近部署。阅读this了解更多详情。