How to save an incoming filestream from Node into AngularJS - javascript

On my express server I have a post-request which is getting a pdf file from Amazon S3 and sending it back to angular. This is how my express server endpoint ends with:
var fileStream = s3.getObject(options).createReadStream();
fileStream.pipe(res);
On the angular side of things I am posting and trying to save this
$http.post(url, data)
.then(function (data, status, headers, config) {
var file = new Blob([data.data], {type: 'application/pdf'});
FileSaver.saveAs(file, vm.projectName);
})
I get a pdf file which is not valid. I has about 300kb (more than original file) and I believe its not pdf but a buffer?
What I am trying to achieve:
- Post Request to server
- Server gets file from S3, Sends it back to Angular Controller
- Angular Controller saves it as .png

When you're making POST call, set responseType of request to arrayBuffer inside configuration, so that response will get transformed to correctly.
$http.post(url, data, {responseType: "arraybuffer"})

Related

Vue JS how to accept the URLEncoded format

I am trying to accept the URL Encoded format in postman to post some data to the Vue JS app, I am using the below-encoded format, how can I achieve that which npm package should I use?
you can use axios
const axios = require('axios')
const params = new URLSearchParams()
params.append('name', 'Akexorcist')
params.append('age', '28')
params.append('position', 'Android Developer')
params.append('description', 'birthdate=25-12-1989&favourite=coding%20coding%20and%20coding&company=Nextzy%20Technologies&website=http://www.akexorcist.com/')
params.append('awesome', true)
const config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
axios.post(url, params, config)
.then((result) => {
// Do somthing
})
.catch((err) => {
// Do somthing
})
x-www-form-urlencoded data is sent via HTTP headers
Most HTTP headers are not visible to your front-end JavaScript application. They are only visible to the server responding to the request. You cannot read them directly from JavaScript running in a web browser.
However, there are options...
Change the source; have the POST request changed to a GET and encode the parameters in the URL
A reverse proxy for your application could convert from POST parameters to GET parameters with some additional coding or configuration
Receive the request on your server and feed them into your Vue.js application; use something like php/asp/etc to serve your html instead of static HTML files and embed the posted parameters in the generated HTML page
There may be other options if you are creative, but the simplest is the first - just change the source so it no longer posts data.
I resolved it by adding middleware(server-side code such as .net web API) and then redirected it using query string)

JavaScript - Axios POST request empty form data (request payload)

I have a Vue.js app which uses axios to interact with a Laravel API. I'm trying to make a POST request with an image file in it to upload in the backend.
The issue I'm having is that axios makes the POST request with empty payload.
I've tried sending it both as a plain JS object and with FormData. In both cases the request payload is empty. I've looked on the internet for hours but I was unable to find anything while trying to tackle the issue in the past few days...
This is how I make the request:
let fd = new FormData();
fd.append('file', this.file);
console.log(...fd) //shows the file is there with its data
axios
.post("/api/images", fd)
.then(response => {
//Handle success
})
.catch(errors => {
//Catch errors
});
This is how I get the file from the form:
let selectedImage = this.$refs.fileInput.files[0];
const reader = new FileReader();
reader.addEventListener('load', (event) => {
this.file = event.target.result;
});
reader.readAsDataURL(selectedImage);
I've tried experimenting with the request headers and at the moment they are as follows:
"Accept" : "application/json",
"Content-Type": "multipart/form-data; charset=utf-8; boundary=" + Math.random().toString().substr(2),
"Authorization": "Bearer " + this.user.api_token,
"X-CSRF-TOKEN": document.querySelector('meta[name="csrf-token"]').content
The responses from Laravel are always that the file is required (as expected when it's indeed missing).
I did try encoding the file in Base64 but I have trouble validating that it's an image in the backend.
I found this similar question but it wasn't of any help: FormData sends empty data using axios
I want to send a file + JSON data but I'm ok with just making the file upload work. So... How do I send a file from Vue.js app to Laravel API using Axios? What am I doing wrong?

How to send a file uploaded by javascript and get it received in a flask app and send it as post request to another server?

When i try to send a post request from flask using the file, which is received via the ajax request from client side, I am getting an exception:'too many values to unpack (expected 2)
I have a client side app which uploads a file(Javascript).
I have my server code which acts as a proxy which deals with all external server calls. The uploaded file gets send to this server as a post request from client side.
Now i need to send this file received in my server to an external server as a post request using requests module in python.
I am stuck with an exception when i am doing step 3.
I am not sure if it is the right way to post such files as i am new to flask. Please give some inputs which might help.
Client side code
$('input[type="file"]').change(function (e) {
var formData = new FormData(e.target.files[0]);
var fileName = e.target.files[0].name;
var fileType = e.target.name;
var settings = {
"async": true,
"crossDomain": true,
"url": "/upload?file_name="+fileName+"&file_type="+fileType,
"method": "POST",
"contentType": false,
"cache": false,
"processData": false,
"data": formData
};
$.ajax(settings).done(function (response) {
console.log(response);
});
});
Flask code
#app.route('/upload', methods=['GET','POST'])
def uploadToExternalServer():
if request.method == "POST":
try:
file_content=request.files['file']
file_type= request.args.get('file_type')
file_name= request.args.get('file_name')
url="url to post with params"
response = requests.post(url, auth=('usr', 'pwd!'),files=file_content)
return r
except Exception as e:
logging.info(e.args[0])
Expected:
Should be able to successfully post the file to the external server
Actual:
Getting an exception at post request as :'too many values to unpack (expected 2)
Check the documentation of Requests
I think your problem is that you are trying to do your post passing the file like an object, and the param expects an dictionary.
files – (optional) Dictionary of 'name': file-like-objects (or {'name': file-tuple}) for multipart encoding upload. file-tuple can be a 2-tuple ('filename', fileobj), 3-tuple ('filename', fileobj, 'content_type') or a 4-tuple ('filename', fileobj, 'content_type', custom_headers), where 'content-type' is a string defining the content type of the given file and custom_headers a dict-like object containing additional headers to add for the file.

python - send pdf as bytes in web services

I use to build a web service that response with application-json mime type.
But now I want to response a PDF as bytes, so I assume that I have to change mime type.
I will use routing but I could use flask-restful too.
The following code show the structure but I don't know how covert pdf to bytes and then send it.
#app.route('/pdf/myfile')
def pdf():
data = open("myfile.pdf", "rb").read()
# make a reponse with those bytes
return response
In the client side (angular.js) I will have this:
$http.get('/pdf/myfile', null, { responseType: 'arraybuffer' })
.success(function (data) {
var file = new Blob([data], { type: 'application/pdf' });
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
});
You can use send_file or send_from_directory:
from flask import send_from_directory
#app.route('/pdf/myfile')
def pdf():
return send_from_directory('/dir/of/pdf', 'my.pdf')
By default this will send the file inline and browsers will probably render the PDF itself. If you set as_attachment=True the file will be presented as an attachment, and the browser will throw up a "save as" dialog box.
send_file gives you more control over things such as mime types and caching. The defaults should work well.

Receiving POST request with node.js

I have an Axis M1011 camera which is set up to send a series of jpeg images as long as it is detecting motion, to a service (using HTTP POST). I'm building the service using node.js.
I'm successfully receiving POST requests with their headers, but I am having trouble saving the data in the body of the request. Here is the code:
function addEvent(req, res)
{
var buffer = '';
console.log(req.headers);
req.on("data", function(chunk)
{
console.log("chunk received");
buffer += chunk;
});
req.on("end", function()
{
console.log("saving file");
fs.writeFile("./tmp/"+ new Date().getTime()+".jpg", buffer, function(error)
{
if(error)
{
console.log(error);
}
else
{
console.log("saved");
res.send("OK");
res.end();
}
});
});
}
On the console, I get this kind of output. Ofcourse, the content-length differs from file to file:
{ host: '192.168.0.100:8888',
'content-type': 'image/jpeg',
'content-disposition': 'attachment; filename="file13-07-19_20-49-44-91"',
'content-length': '18978' }
chunk received
chunk received
chunk received
chunk received
chunk received
chunk received
chunk received
chunk received
chunk received
chunk received
chunk received
chunk received
chunk received
chunk received
saving file
saved
The problem is that I am getting one same, corrupted, file in the tmp folder which size is about 33KB, no matter how big is the image. What am I doing wrong with receiving these files?
You need to process the POST request to get the file that has been sent. When you submit a file in POST request, you wrap file meta data as well as data and send it to the server.
The server has to decode the request, and get the file. Simply saving the request won't do. You did not mention if you are using any web-server framework. It is better you use one like express which does this for you. Express will parse the request, get the file object and save the file into temporary file.

Categories

Resources