uploading files to s3 using coffeescript - javascript

I am trying to upload files using pre-signed url to s3 bucket. I am getting the pre-signed url by hitting a rest endpoint, which returns a json with the required details.
Now, I have to take this json and get the input file from user, to upload the file.
Here is the code, I have written in coffeescript. I am taking an input file obj from user and storing in file object and then calling the pre-signed api to get the json.
uploadFile: (e) =>
files_container = e.target.form.elements[0].files
if files_container.length > 0
#file_obj = files_container[0]
console.log(#file_obj)
result = ""
$.ajax
type: 'GET'
url: '/api/upload/get_lead_upload_url'
dataType: "json"
success: (response) ->
console.log(response)
Below, I have to write this python code in coffeescript to upload the file.
with open(object_name, 'rb') as f:
files = {'file': (object_name, f)}
http_response = requests.post(response['url'], data=response['fields'], files=files)
# If successful, returns HTTP status code 204
Below is the part, where I am going wrong while creating the payload like the python code.
formdata = new FormData
formdata = response.fields
formdata['file']= {#file_obj['name'], #file_obj}
console.log(formdata)
The post request is giving me 403 forbidden error.
$.ajax
type:'POST'
dataType: "jsonp"
url: response.url
headers: {'Access-Control-Allow-Origin': '*'}
data: formdata
success: (uploadResponse) ->
console.log(uploadResponse)
error: (uploadResponse) ->
console.log('error')
console.log(uploadResponse)
error: (response) ->
console.log('error')

Related

Sending a csv from front-end to backend using axios

I am trying to send a csv file from my front end in reactjs to my back end in nodejs using axios. This csv file is selected via a browse UI button and stored in state using react. After searching online this is my code for the HTTPS request:
let formmData = new FormData();
formData.append('file', this.state.selectedFile);
const {data : QueryResult} = await axios({
method: 'post',
url: "https://localhost:...",
formData,
});
Note: this.state.selectedFile contains an object which when logged on console is:
File {name: "MyFile.csv", lastModified: 1614958303483, …}
I also would like to say that this endpoint works fine when using Postman as seen below:
After printing the request in my back-end in the case this request from my frontend I see:
body: {}
I don't understand what I am doing wrong and this passes nothing to my back-end.
I also saw that this was an open issue with axios on GitHub in the past.
Can this be achieved now with axios or should i use another module? Any ideas?
You need to do:
await axios({
method: 'post',
url: "https://localhost:...",
data: formData
});
because when you write just "formData", it becomes : { formData: formData } as per (new ES2015 object shorthand property name).
You can also use:
await axios.post('your_url', formData)

Django request.FILES gets name, filename but not file (blob)

I'm trying to send an audiofile via a POST request to the server (aws, ec2) and I'm using Django, but my request.FILES doesn't receive the blob file, but it DOES receive the key and the filename.
Everything worked fine when I ran this on localhost.
How can I get the file?
I'm enabling my website on chrome://flags/#unsafely-treat-insecure-origin-as-secure, so that I can access the microphone.
Using RecorderJs to generate a Blob object containing the recorded audio in WAV format.
Main.js
rec.exportWAV(function(blob){
...
var fd = new FormData();
fd.append('text', speech);
fd.append('audio', blob, 'test.wav');
$.ajax({
type: 'POST',
enctype: 'multipart/form-data',
url: url,
data: fd,
processData: false,
contentType: false,
success: function(response) {
console.log(response);
}
})
...
speech is String,
blob in console is Blob {size: 221228, type: "audio/wav"}, so it does exist.
Views.py:
#csrf_exempt
def get_blob(request):
thislist = []
for key in request.POST:
thislist.append(request.POST.get(key))
for key in request.FILES:
thislist.append(request.FILES.get(key).name)
json_stuff = json.dumps({"check": thislist})
return HttpResponse(json_stuff, content_type="application/json")
I've tried with and without enctype, doesn't make a difference.
I've tried setting contentType to multipart/form-data, doesn't make a difference.
The formdata seems to be sent correctly, because I can get the speech correctly (request.POST).
And I can get the key from request.FILES ('audio'), and get the filename ('test.wav').
If I try request.FILES['audio'].read(), it says MultiValueDictError.
If I try request.FILES.get('audio').read() it says AttributeError, 'NoneType' object has no attribute 'read'.
When I print request.POST I do get the dictionary with 'text': whatever text I've spoken.
When I print request.FILES I get an empty dictionary even though I can get the key and filename through
for key in request.FILES: and request.FILES['audio'].filename.
Does anyone know what's going on and/or can help me with the problem?
You may use read() method for it:
#csrf_exempt ## it doesn't work for post requests in later Django versions, so you need to disable it in another way or add a token to all post requests
def get_blob(request):
thislist = []
for key in request.POST:
thislist.append(request.POST.get(key))
for key in request.FILES:
thislist.append(request.FILES.get(key).name)
# I am not sure that "name" exists in the request — you may use any filename, although the following works with multipart requests.
with open(request.FILES["name"],"wb+") as f:
f.write(request.FILES['file'].read())
json_stuff = json.dumps({"check": thislist})
return HttpResponse(json_stuff, content_type="application/json")
By the way,
#csrf_exempt — doesn't work for post requests in later Django versions, as a token is checked before your view is even called. So, you may need to disable CSRF middleware or just add a correct 'X-CSRFToken' token to all requests.

JQuery ajax form submit for return file giving undefined error response [duplicate]

This question already has answers here:
Download pdf file using jquery ajax
(5 answers)
Closed 4 years ago.
Due to various issues with security of file manipulation, I am forced to submit the request via Ajax post method call. The server side URL receives this and gives out a pdf file as response. Server side code in java servlet is as below.
ServletOutputStream out = response.getOutputStream();
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment;filename=" + outFile);
//create the pdf file
response.flushBuffer();
On the client side, the javascript code is sending call to a POST which calls the above code via doPost. When the form is submitted through form.submit(), the file gets downloaded nicely as pdf file. When trying through Ajax call, it is giving me undefined response under error section. Client side code as below.
var formData = new FormData();
//Fill formData with fields and files
console.log('Posting form from ajax');
$.ajax({
url: "/createPdf",
type: "POST",
data: formData,
contentType: false,
processData: false,
xhrFields: {
responseType: 'blob'
},
success: function (response, status, xhr) {
console.log('Processing response');
download(response, "merged.pdf", "application/pdf" );
},
error: function (xhr, status, error)
{
var err = xhr.responseText;
alert(err);
}
In the above, it is not going under success response. It is going under error and alerting as undefined. What am I doing wrong here. My jquery version is 1.8.0.min.js if that matters. download function refers to http://danml.com/download.html but I have tried the other snippets too but it doesn't even come to success.
Under Inspection tools, I see success request and blob data in response, but it takes about 10-15 seconds for the blob data to show under Network in browser
Please help. I have been at it all evening and can't seem to figure out undefined response.
For ajax download you should dynamic add link, trigger click and then delete.
var formData = new FormData();
//Fill formData with fields and files
console.log('Posting form from ajax');
$.ajax({
url: "/createPdf",
type: "POST",
data: formData,
contentType: false,
processData: false,
xhrFields: {
responseType: 'blob'
},
success: function (response, status, xhr) {
var a = document.createElement('a');
var url = window.URL.createObjectURL(response);
a.href = url;
a.download = 'myfile.pdf';
a.click();
window.URL.revokeObjectURL(url);
},
error: function (xhr, status, error)
{
var err = xhr.responseText;
alert(err);
}
You mentioned in your form.submit () it works without any issue. What type are you using, POST or GET? I World try to change it in your ajax request. I'm no java pro but maybe your Servlet only reacts to GET requests. When I worked with Ajax and Servlets I used http Servlet where I overwrote the doGet method.

415 Unsupported Media Type Using JQuery/FormData and Web Api

I'm getting a Error :
"POST {URL} 415 (Unsupported Media Type)" error
And cannot figure out why it's happening.
I'm trying to upload an excel file in JQuery using FormData.
Here is the code:
var formdata = new FormData();
var file = input.get(0).files[0];
formdata.append('content', file);
var url = "/Phrase/Import/" + $('.exportPanel #Language').val()
var ajax = $.ajax({
url: url,
type: "POST",
data: formdata,
processData: false,
contentType: false,
success: function (data, textStatus, jqXHR) {
//Do something.
},
error: function (jqXHR, textStatus, errorThrown) {
//Do something.
}
});
Here is the controller code:
[Route("Import/{languageID}")]
[HttpPost]
public void ImportPhrases([FromUri]int languageID, [FromBody]Stream content)
{
_service.ImportPhrases(content, languageID);
}
I noticed that, according to Fiddler, the content type of the request is different to that of the response (not sure if this makes a difference?).
Request: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Response: application/json; charset=utf-8
The JQuery above is being used in a different part of the system, but uses WCF instead of Web API (am in the process of changing from WCF to MVC/Web API), again I'm not sure if this makes a difference?
Can anyone tell me what I'm doing wrong please?
Many thanks.
415 Unsupported Media Type
The request entity has a media type which the server or resource does not support. For example, the client uploads an image as image/svg+xml, but the server requires that images use a different format.
contentType does matter - it tells the server what you are uploading. In this instance, you have set the value to false. The server cannot recognise this, so it returns false. If you do not need a specific content type, you should remove the contentType line to allow the jQuery default to kick in.

Sign URL for Upload to S3, Javascript & Boto

I'm trying to upload a file to Amazon AWS from Javascript with a signed URL obtained from a django api where I sign it with the help of Boto. This is my line in python:
url = conn.generate_url(300, 'PUT', settings.AWS_VIDEO_BUCKET, key, headers={'Content-Length': '19448423'}, force_http = True )
Using the URL generated from this, I can post to S3 with CURL like so:
curl -v --request PUT --upload-file video.mp4 "http://some_signed_url"
What does not work though, is using this URL to PUT a file to Amazon AWS via Javascript. Debugging with a proxy reveals a broken pipe error, while CURL would give me the regular Amazon Access Denied XML if something went wrong. This is my javascript code (file is a JS File object):
var file = e.originalEvent.dataTransfer.files[0];
var fd = new FormData();
fd.append( 'file', file );
$.ajax({
url: 'signed_url',
data: fd,
processData: false,
contentType: false,
cache: false,
type: 'PUT',
success: function(data){
console.log("success");
},
error: function(data){
console.log(data.responseText);
}
});
Any ideas where to go from here? Maybe I'm not including all the required headers in the signing process, or FormData is not the right way to go.

Categories