Post Blob Image to django rest framework with ajax - javascript

I have a html page that allows a user to take a screenshot from their camera.
This screenshot is then rendered in the page with the function from main.js down below.
If i do console.log(image) i get image tag with a src to a blob:http that has the image.
Now for the fun part. I want to post this image to my api in django rest framework.
Basically how do i go from a blob image to a post request to the api?
I tried using $.ajax but I dont know how to format the "blob data" to be accepted for the "data:" parameter field in ajax.
Note also that i'm not using forms in the html, when i do that the html page gets refreshed as soon as i take a screenshot so the image does not stay on the page..
If I have to use forms in order to make this work, please let me know and I will try another approach.
main.js
async function grabFrame() {
const img = await imageCapture.grabFrame();
const url = URL.createObjectURL(await imageCapture.takePhoto());
document.querySelector("img").src = url
#id_image is where the screenshot is located
const image = document.getElementById('id_image')
console.log(image)
index.html
<button onclick="grabFrame()">Grab Frame</button>
<img id="id_image" style="width:320px; height:240px"/>
models.py
class Image(models.Model):
image = models.ImageField(upload_to='media/')
serializer.py
class ScreenshotCreateSerializer(ModelSerializer):
class Meta:
model = Image
fields = [
'image'
]
views.py
class SaveScreenshot(CreateAPIView):
serializer_class = ScreenshotCreateSerializer
permission_classes = [AllowAny]
def home_view(request):
return render(request, 'index.html', {})
what i tried in the main.js
// $.ajax({
// url: "/api/save_screenshot",
// type: "POST",
// processData: false,
// mimeType: "multipart/form-data",
// contentType: false,
// data: blob data?,
// success: function (data) {
// alert("Screenshot saved successfully!");
// },
// error: function (e) {
// console.log(e);
// }
// }).done(function(o) {
// });

Related

Sending a file and json data with AJAX

I have tried two methods of sending the file and json data from client side over to server side. I been partially successful with both methods, I could use some help on completing this. I have two methods:
Method 1: I am able to access the file server side, but my form data (input, select, textarea) are not available to access.
Method 2: Appends the data to the formData object. The issue with method one is that I got it to work the other day, but I believe my browser cached the code and now its not working, so I feel like im back at step one. I am able to access the data by using request.data, but its bytes. The code that was working (request.form['json_data'] or request.files['file'].read()) and now its not working.
Client Side Code:
$('form[name="upload-form"]').on('submit', (event) => {
event.preventDefault();
$('#form-loader').fadeIn()
// Method 1
// let formData = new FormData($('#upload-form')[0]);
// Method 2
let entry = get_form_entry('upload-form'); -> UDF to get all form data. Iterates each form data and applies .val() and creates a dict.
const formData = new FormData();
formData.append('json_data', JSON.stringify(entry));
formData.append('file', $('#file')[0].files[0]);
$.ajax({
data: formData,
url: '/newEntry',
type: 'POST',
contentType: false,
processData: false,
cache: false,
success: function () {
$('#form-loader').fadeOut()
},
error: function () {
$('#form-loader').fadeOut()
},
})
})
Server Side Code:
json_data = request.form['json_data']
# json_data = request.data
file_data = request.files['file'].read()

How to show AJAX response data on a website

I'm writting a Spring Boot applicaiton in which I have a website with a submenu with several computer games. When I click on an position in this submenu, I want server to send an image (by image I mean a path to the image) of this game as a response, and after the response comes back to my JS on a website, I want to show it on the website. What I have already done is sending a request to server, and selecting an image based on request data. I don't know how to send a response and use it on my website.
Here is my code:
Java:
#RequestMapping("/change-game")
public String changeGame(HttpServletRequest request, #RequestBody GameData data){
File file;
String game = data.getName();
switch (game) {
//some code which actually works. I removed it to save space
}
request.setAttribute("gameIcon", file);
return "index";
}
JavaScript:
$("#selectGameSubmenu li").click(function(e){
e.preventDefault();
var option = $(this).data("option");
console.log(option + " " + JSON.stringify({"option": option}));
$.ajax({
type: "POST",
url: "http://localhost:8080/change-game",
data: JSON.stringify({name: option}),
contentType: "application/json; charset=utf-8",
dataType: "json"
});
});
HTML:
<img src="${gameIcon}" alt="${altGameIcon}"
style="width:100px;height:100px" class="gameLogoCenter"/>
I would add a new method that returns only the image path for your AJAX calls to consume.
For example
#ResponseBody
#PostMapping("/change-game-icon")
public String changeGameIcon(#RequestBody GameData data) {
File file;
String game = data.getName();
switch (game) {
//some code which actually works. I removed it to save space
}
return file.toString();
}
and in your JS
$.ajax({
url: '/change-game-icon',
method: 'post', // or "type" if your jQuery is really old
data: JSON.stringify({name: option}),
dataType: 'text',
contentType: 'application/json'
}).done(iconPath => {
$('img.gameLogoCenter').prop('src', iconPath)
})

How can I download a word document created by a django app on the same app

I have a django app the creates a word document from a template. After user input I make an ajax request to my views.py and create the document. After the document is created I want it to be downloaded from the server. The document is saved in the static/documents folder. In my template I have the following:
$.ajax({
url: '/ajax/result/',
data : { 'values': JSON.stringify(dataJson),
'general': JSON.stringify(generalData)
},
method: 'GET',
contentType: "application/json",
dataType: 'json',
success: function (data){
Download('documents/'+document.getElementById('id_file_name').value+'.docx');
alert(data);
},
error: function(data) {
alert("something went wrong");
}
});
function Download(url) {
document.getElementById('my_iframe').src = url;
};
The Download(url) function is the function that downloads the document. I can get the file name of the document since it is from user input. I am currently getting a 404 error on my console.
Thanks in advance
You need to be declare actual file path
Download('http://127.0.0.1:8000/something/something/documents/'+document.getElementById('id_file_name').value+'.docx');
If you can use this Technic to your views:
file_name = ## your file name
file_root = ## your file root
with open(file_root , 'rb') as f:
wrapper = FileWrapper(f)
mimetype = "application/force-download"
guessed_type = guess_type(file_name)[0]
if guessed_type:
mimetype = guessed_type
response = HttpResponse(wrapper, mimetype)
response['Content-Disposition'] = "attachment;filename=%s"%(download_obj.get_name)
response['X-SendFile'] = "%s"%(download_obj.get_name)
return response
Don't forget to import necessary things on the top your views.py file:
from django.shortcuts import HttpResponse
from mimetypes import guess_type
from wsgiref.util import FileWrapper
Create a new url for this views, and hit the url from ajax, you can pass dynamically file name to the view

Rails 4: Unpermitted parameter

I have a model Picture where I take a photo with webcam and save it. I upload the images with carrierwave, and generate the image with the gem carrrierwave-data-uri The image is sent by ajax
the function on my PicturesController.rb is:
def upload_image
photo = params[:picture][:photo]
#picture = Picture.new(picture_params)
#picture.user_id = current_user.id
#picture.photo = photo
#picture.save
end
private
def set_picture
#picture = Picture.find(params[:id])
end
def picture_params
params.require(:picture).permit(:photo, :comment, :user_id )
end
end
My Ajax
function save_photo() {
Webcam.snap( function(data_uri) {
$.ajax({
type: 'POST',
url: '/pictures/upload',
async: true,
data: { picture: {photo: data_uri} }
})
.done(function () {
console.log(photo);
});
Webcam.reset();
} );
}
When I send the image, it is registered on database, but not the image. I getting the console error:
Unpermitted parameter: image
But if I add the parameter :image on my strong parameters, I get the Completed 500 Internal Server Error
The data uri is printed on my console, but I can't put it in a image variable
Thanks by help!
You get 500 Internal Server Error when permitting image because you don't have an image attribute in the model. You have photo instead, so you should use it as the parameter to send data_uri in the ajax method.
Change image in the AJAX call to photo:
data: { picture: { photo: data_uri } }
Also make change in your controller method like this:
def upload_image
#picture = Picture.new(picture_params)
#picture.user_id = current_user.id
#picture.save
end

how to upload file on django server using javascript/jQuery and ajax

After having spent hours, I need help to match the javascript code to the django codes.
I am using the "minimal-django-file-upload-example" version django 1.8 from the git https://github.com/axelpale/minimal-django-file-upload-example.
In standalone, it works very well.
Now i try to upload file from javascript and i do not succeed to make it works.
Javascript Code
function UploadBlob(zip)
{
var ZipFileBlob = zip.generate({type:"blob"});
var fd = new FormData();
fd.append('data', ZipFileBlob);
fd.append('fname', 'ZipOfImage.zip');
fd.append('enctype','multipart/form-
$.ajaxSetup({
type: 'POST',
url: 'http://127.0.0.1:8000/myapp/list/',
enctype: "multipart/form-data",
headers: { "X-CSRFToken": getCookie("csrftoken") }
});
$.ajax({
data: fd,
processData: false,
contentType: false
}).done(function(data) {console.log(data);});
}
Django code
in forms.py
class DocumentForm(forms.
docfile = forms.FileField(label='Select a file')
in views.py
def list(request):
# Handle file upload
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
newdoc = Document(docfile = request.FILES['docfile'])
newdoc.save()
# Redirect to the document list after POST
return HttpResponseRedirect(reverse('myproject.myapp.views.list'))
else:
print "invalid form"
else:
form = DocumentForm() # A empty, unbound form
# Load documents for the list page
documents = Document.objects.all()
# Render list page with the documents and the form
return render_to_response(
'list.html',
{'documents': documents, 'form': form},
context_instance=RequestContext(request)
)
The code run up to the request.method == 'POST'. After, i do not know if i should add field to the ajax requests (and which ones) or if there is a more suitable form in django or do something else.
Please help!

Categories