Reputation: 4863
I have a user form where a user can pick a file on their system and upload it to another server using the FormData. It works fine when testing sending it directly to the api. But I need to modify the headers before sending it. So I'm posting to the backend of the client app.
router.post('/upload', function(req, res, next) {
//...some axios or request logic
var fs = require('fs');
var request = require('request');
var formData = {
my_field: 'my_value',
my_file: fs.createReadStream(__dirname + '/example.doc'),
};
request.post({url:'http://someothereapp/upload-file', formData: formData}, function(err, httpResponse, body) {
if (err) {
return console.error('upload failed:', err);
}
console.log('Upload successful! Server responded with:', body);
res.send('good!');
});
});
axios
or request
works great for posting normal forms or get request. But when I try to use it to send a file it doesn't work. The above code always returns success but does not upload the file. So i went here and still don't understand enough to see what I am missing.
I have authentication and tracking turned off on the other server (local) while testing so i don't have to modify headers. It has the following code that works fine if I send the file directly to it from the web form, but not from my client express app:
// http://someothereapp/upload-file
router.post('/upload-file', (req, res, next) => {
let multer = require('multer')
let p = path.join(__dirname, '../uploads');
let storage = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, p )
},
filename: function(req, file, callback) {
console.log('what is file', file)
callback(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname))
}
})
let upload = multer({
storage: storage
}).single('userFile')
upload(req, res, function(err) {
res.end('File is uploaded')
})
});
I saw this issue and think it might mean its not possible with axios but how do you do it with request? For example, in the post ... upload
code, how do i get my_file
to be the file the user selected in their form? Why is it not failing even though it's not uploading a file?
Upvotes: 2
Views: 2151
Reputation: 4863
I changed the client backend app to the following and it allows me to modify headers and send the form:
router.post('/upload-file', function(req, res, next) {
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer({headers: customHeader});
proxy.web(req, res, { target: 'http://someothereapp' }, function(e) {
// will proxy request to http://someothereapp/upload-file
...
});
});
The client form (unchanged):
<form name='uploadfile' enctype="multipart/form-data" method="post">
<input type="file" name="userFile" />
<input type="submit" value="Upload File" name="submit">
</form>
<script>
var form = document.forms.namedItem("uploadfile");
form.addEventListener('submit', function(ev) {
var oOutput = document.querySelector("div"),
oData = new FormData(form);
var oReq = new XMLHttpRequest();
oReq.open("POST", "/upload-file", true);
oReq.onload = function(oEvent) {
if (oReq.status == 200) {
// oOutput.innerHTML = "Uploaded!";
console.log('Uploaded');
} else {
console.log('error', oReq.status);
// oOutput.innerHTML = "Error " + oReq.status + " occurred when trying to upload your file.<br \/>";
}
};
oReq.send(oData);
ev.preventDefault();
}, false);
</script>
The target server (unchanged):
// http://someothereapp/upload-file
router.post('/upload-file', (req, res, next) => {
let multer = require('multer')
let p = path.join(__dirname, '../uploads');
let storage = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, p )
},
filename: function(req, file, callback) {
console.log('what is file', file)
callback(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname))
}
})
let upload = multer({
storage: storage
}).single('userFile')
upload(req, res, function(err) {
res.end('File is uploaded')
})
});
Upvotes: 1