Django ajax return a html page - django

I am trying to decrypt encrypted text and return the plain text through ajax call, instead of getting the message response I get an HTML page back as a response. I have tried returning the response as JSON but still getting the same HTML response.
function loadMessage() {
fetch("{% url 'chat:history' chatgroup.id %}")
.then( response => response.json() )
.then( data => {
for (let msg of data) {
var message=msg.message;
$.ajax({
type: 'GET',
url: '',
data: { message: message},
success: function(response){
broadcastMessage(response.message, msg.username, msg.date_created)
}
})
}
})
}
views.py
def get(request):
message = request.GET.get('message')
key = b'\xa8|Bc\xf8\xba\xac\xca\xdc/5U0\xe3\xd6f'
cipher = AES.new(key, AES.MODE_CTR)
nounce = b64encode(cipher.nonce).decode('utf-8')
if request.is_ajax():
nounce_ = self.nounce
msg_ = self.message
key = self.key
nounce = b64decode(nounce_)
ct = b64decode(msg_)
cipher = AES.new(key, AES.MODE_CTR, nounce=nounce)
msg_ = cipher.decrypt(ct)
mwssage = msg_.decode()
return JsonResponse({'message': message})
return render(request, 'chat/room.html')

The path to the decryption view was empty, after adding a path in the url it worked.

Related

Why is flask jsonify returning unidentified?

I am using fetch on the frontend to send data to my flask backend in order to make a movie seat booking. The whole process works fine until the client awaits the response, which is "undefined" . So , basically the database saves the data , the only problem is the response which is sent to the client. I used jsonify which usually works fine. Can anybody tell me what I am missing? Thanks in advance.
Here is the JS code :
function sendReservationToServer() {
const selectedSeats = sessionStorage.getItem('selectedSeats')
const reservation = { userId, selectedSeats, showTimeId, movieHallId }
fetch('/bookSeats', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(reservation)
}).then(response => {
response.json()
}).then(data => {
theatreHall.innerHTML = `${data} <br> <a href='/home'>Back to main menu</a>`
console.log(`${data}`)
}).catch(err => infoMsg.textContent = err)
sessionStorage.clear()
}
And this is the flask controller which handles the request:
#app.route("/bookSeats", methods=["POST"])
def book_seats():
selected_seats = request.json
user_id = selected_seats.get('userId')
seats = json.loads(selected_seats.get('selectedSeats'))
movie_hall_id = selected_seats.get('movieHallId')
seat_ids = []
showtime_id = selected_seats.get('showTimeId')
for seat in seats:
seat_ids.append(db.session.query(Seat).filter(
Seat.seat_number == seat).filter(Seat.movie_hall_id == movie_hall_id).all()[0].stid)
for seat in seat_ids:
reserved_seat = ReservedSeat(
seat_id=seat, show_time=showtime_id, user=user_id)
db.session.add(reserved_seat)
db.session.commit()
reservation = Reservation(
user=user_id, show_time=showtime_id, number_of_tickets=len(seat_ids))
db.session.add(reservation)
db.session.commit()
message = f'{seats} booked successfully'
return jsonify(message)
data is undefined because the first then does not return anything. Either make it return response.json() or move everything in the second then to the first and replace data with response.json().

Django : Binary File Download on Button click returning incorrect data

Implemented file download on button click for a binary file using Ajax and Django as below
Django Code
def generate(self,parms):
#pdb.set_trace()
json_data = json.loads(parms.body.decode('utf-8'))
d_fldr = BASE_DIR+'/tmp/'+json_data['sessn']+'/'
resp = None
try:
data = None
with open(d_fldr + json_data['fn'],'rb') as f:
data = f.read()
resp = HttpResponse(data,'application/octet-stream')
resp['Content-Disposition'] = 'attachment;filename=%s'%(json_data['fn'])
except:
resp = None
return resp
AJAX Call on Button Click
function ajax_file_send(req,onSucc,onFail) {
req['beforeSend'] = function() {
$('#loading').modal({backdrop: "static"});
}
req['complete'] = function(){
$('#loading').modal('hide')
}
req['error'] = onFail;
req['success'] = onSucc;
$.ajax( req );
}
....
.....
$('#btn_gen').on('click',function(e) {
console.log("Generate clicked");
json = { 'sessn' : global_sessn,
'fn' : $('#kdb_sel').val(),
'xml' : $('#kdb_xml').val()
};
var req = {
url: "ajx_generate",
method: "post",
processData: false,
contentType: false,
headers: { "X-CSRFToken": '{{ csrf_token }}'
},
data: JSON.stringify(json),
//responseType: 'arraybuffer',
};
ajax_file_send(req,fun_succ1,fun_fail1);
function fun_succ1(response) { // on success..
console.log("fun_succ1 success");
var binaryData = []; binaryData.push(response);
var a = document.createElement('a');
var url = (window.URL || window.webkitURL).createObjectURL(new Blob(binaryData, {type: "application/kdb"}));
a.href = url;
a.download = $('#kdb_sel').val();
document.body.append(a);
a.click();
a.remove();
window.URL.revokeObjectURL(url);
}
Issue
The file that gets downloaded(2KB) on button click, is more in size than that is originally on server (1.4Kb) , while on Network TAB in DEV Tools Header : Content-Length is correctly set to 1.4Kb

Django can only concatenate str (not "list") to str

Django can only concatenate str (not "list") to str
Error Messages.......
I have some code like this:
function form_submit() {
var arr_category = new Array();
var arr_lawyer = new Array();
var data = new Object();
$('input[name^="category_idx"]').each(function() {
arr_category.push($(this).val());
});
$('input[name^="lawyer_idx"]').each(function() {
arr_lawyer.push($(this).val());
});
console.log("arr_category=="+arr_category);
console.log("arr_lawyer=="+arr_lawyer);
if (confirm('edit??') == true) {
data.arr_category = arr_category;
data.arr_lawyer = arr_lawyer;
call_ajax('/admin/lawyer/recommend_add', data);
//alert("arr_lawyer=="+arr_lawyer);
}
}
Am I doing well in jquery?
look at console.log
arr_category==1,2,3,4,5,6,7,8,9
arr_lawyer==64,37,57,58,130,62,38,51,110
admin_view.py
#csrf_exempt
def recommend_add(request):
print("TEST BANG VALUE------------")
if request.is_ajax() and request.method == "POST":
arr_category = request.GET.getlist('arr_category[]')
print("arr_category------------" + arr_category)
code = 0
msg = "TEST."
data = json.dumps({
'code': code,
'msg': msg,
#'retURL': retURL
})
return HttpResponse(data, content_type='application/json')
I want to print.
error message
TypeError: can only concatenate str (not "list") to str
How can I do that?
In case if you want to return a python interpreter error message to jquery's ajax call then you can use the below syntax.
def recommend_add(request):
print("TEST BANG VALUE------------")
if request.is_ajax() and request.method == "POST":
try:
arr_category = request.GET.getlist('arr_category[]')
print("arr_category------------" + arr_category)
code = 0
msg = "Success"
except Exception as e:
code = '' # anything you want as per your internal logic in case of error.
msg = str(e)
data = json.dumps({
'code': code,
'msg': msg,
#'retURL': retURL
})
return HttpResponse(data, content_type='application/json')
Please ignore my indentation.
in your print code try this
print("arr_category------------:", arr_category)

Django2: Submit and store blobs as image files

I have made a few Django projects after having read the tutorial but I am by no means an expert in Django.
I am trying to take a screenshot of the current page and store it (if one does not exist).
To achieve this, we require a few things:
function to get screen shot of current page
function to async post this image to a view which should store it
view that stores the posted image
However, the screen shot function results in a Blob and I am having trouble getting a Django view to properly handle this.
A demo project is available here: https://gitlab.com/SumNeuron/so_save_blob
Function for screenshot
const screenshot = (function() {
function urlsToAbsolute(nodeList) {
if (!nodeList.length) {
return [];
}
var attrName = 'href';
if (nodeList[0].__proto__ === HTMLImageElement.prototype
|| nodeList[0].__proto__ === HTMLScriptElement.prototype) {
attrName = 'src';
}
nodeList = [].map.call(nodeList, function (el, i) {
var attr = el.getAttribute(attrName);
if (!attr) {
return;
}
var absURL = /^(https?|data):/i.test(attr);
if (absURL) {
return el;
} else {
return el;
}
});
return nodeList;
}
function addOnPageLoad_() {
window.addEventListener('DOMContentLoaded', function (e) {
var scrollX = document.documentElement.dataset.scrollX || 0;
var scrollY = document.documentElement.dataset.scrollY || 0;
window.scrollTo(scrollX, scrollY);
});
}
function capturePage(){
urlsToAbsolute(document.images);
urlsToAbsolute(document.querySelectorAll("link[rel='stylesheet']"));
var screenshot = document.documentElement.cloneNode(true);
var b = document.createElement('base');
b.href = document.location.protocol + '//' + location.host;
var head = screenshot.querySelector('head');
head.insertBefore(b, head.firstChild);
screenshot.style.pointerEvents = 'none';
screenshot.style.overflow = 'hidden';
screenshot.style.webkitUserSelect = 'none';
screenshot.style.mozUserSelect = 'none';
screenshot.style.msUserSelect = 'none';
screenshot.style.oUserSelect = 'none';
screenshot.style.userSelect = 'none';
screenshot.dataset.scrollX = window.scrollX;
screenshot.dataset.scrollY = window.scrollY;
var script = document.createElement('script');
script.textContent = '(' + addOnPageLoad_.toString() + ')();';
screenshot.querySelector('body').appendChild(script);
var blob = new Blob([screenshot.outerHTML], {
type: 'text/html'
});
return blob;
}
return capturePage
})()
Function to async post Blob
function setupAjaxWithCSRFToken() {
// using jQuery
var csrftoken = jQuery("[name=csrfmiddlewaretoken]").val();
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
// set csrf header
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
}
function asyncSubmitBlob( url, blob ) {
var fd = new FormData();
fd.append('image', blob);
$.ajax({
url: url,
type: "POST",
data: fd,
contentType: false,
processData: false,
success: function(response){ console.log(response) },
error: function(data){ console.log(data) }
})
}
So to submit a screenshot of the current page:
setupAjaxWithCSRFToken()
const page = window.location.pathname;
const blob_url = "{% url 'my-app:post_blob' 'REPLACE' %}".replace(/REPLACE/,page == '/' ? '' : page)
asyncSubmitBlob( blob_url, screenshot() )
View to store the posted blob image
urls.py
...
from django.urls import include, path
...
app_name='my-app'
url_patterns=[
...
path('post_blob/', views.post_blob, {'page':'/'},name='post_blob'),
path('post_blob/<page>', views.post_blob,name='post_blob'),
...
]
views.py
from .models import PageBlob
...
def post_blob(request, page):
if request.FILES: # save screenshot of specified page
try:
pb = PageBlob.objects.all().filter(page=page))
if not pb.count():
pb = PageBlob()
pb.page = page
pb.blob = request.FILES['image']
pb.save()
return HttpResponse('Blob Submitted')
except:
return HttpResponse('[App::my-app]\tError when requesting page_image({page})'.format(page=page))
else: # return screenshot of requested page
try:
# get objects storing screenshot for requested page
pb = PageBlob.objects.all().filter(page=page)
# if one exists
if pb.count():
pb = pb[0]
## this just returns the string literal "blob"
return HttpResponse(str(pb.blob))
return HttpResponse('[App::my-app]\tNo blob for {page}'.format(page=page))
except:
return HttpResponse('[App::my-app]\tError when trying to retrieve blob for {page}'.format(page=page))
return HttpResponse('Another response')
models.py
class PageBlob(models.Model):
page = models.CharField(max_length=500)
blob = models.TextField(db_column='data', blank=True)
But I can not seem to faithfully capture and retrieve the blob.
Many S.O. questions of storing blobs use the model approach with import base64 to encode and decode the blob. One even recommends using the BinaryField. However, Django's documentation states firmly that BinaryField is not a replacement for the handling of static files.
So how could I achieve this?
S.O. posts I have found helpful to get this far
Upload an image blob from Ajax to Django
How to screenshot website in JavaScript client-side / how Google did it? (no need to access HDD)
How to download data in a blob field from database in django?
passing blob parameter to django
Returning binary data with django HttpResponse
https://djangosnippets.org/snippets/1597/
Django Binary or BLOB model field
Django CSRF check failing with an Ajax POST request
How can javascript upload a blob?

Unable to get request.FILES django

I am trying to upload a text file to my django backend, but my request.FILES is always empty.
I am using axios to send the file and have followed the django requirement to have 'multipart/form-data' as content type of the request.
What am I missing?
On my app.js I send a post request via:
new Vue({
el: '#app',
data: {
reqtype: '',
uploadedFile: '',
},
methods: {
onSubmit(event) {
this.submitLoading = true;
if (! this.validateForm(this)) {
event.preventDefault();
this.submitLoading = false;
return;
}
var formData = new FormData();
formData.append("reqtype", this.reqtype)
formData.append('fileToUpload', this.uploadedFile)
axios.post('/sreqtool/tc/', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
},
onFileChange(e) {
var files = e.target.files || e.dataTransfer.files;
if (!files.length)
return;
var reader = new FileReader();
var vm = this;
reader.onload = (e) => {
vm.uploadedFile = e.target.result;
};
reader.readAsDataURL(files[0]);
}
},
}
On the network request payload:
------WebKitFormBoundarymAnl54hGVTifZzwM Content-Disposition: form-data; name="reqtype"
filebased
------WebKitFormBoundarymAnl54hGVTifZzwM Content-Disposition: form-data; name="fileToUpload"
data:text/plain;base64,OTA1NTIzMzg2NQ0KOTE3NTAwMTU0Mg0KOTc3NDczNjcyNg0KMTIzNTQ2ODQ1Ng==
------WebKitFormBoundarymAnl54hGVTifZzwM--
In my views.py I have:
#csrf_exempt
def index(request):
if request.method == 'POST':
DLOG.info(request.POST)
DLOG.info(request.FILES)
form = ExtractForm(request.POST, request.FILES)
if form.is_valid():
res = QueryManager.processRequest(request.user, form.cleaned_data)
DLOG is my logger and the output of the dlog is:
[2017-12-18 16:51:06,510] INFO views index: <QueryDict: {u'fileToUpload': [u'data:text/plain;base64,OTA1NTIzMzg2NQ0KOTE3NTAwMTU0Mg0KOTc3NDczNjcyNg0KMT
IzNTQ2ODQ1Ng=='], u'reqtype': [u'filebased']}>
[2017-12-18 16:51:06,512] INFO views index: <MultiValueDict: {}>
it says your image encoded to base64
{u'fileToUpload': [u'data:text/plain;base64,OTA1NTIzMzg2NQ0KOTE3NTAwMT...
I am able to read the file content now.
I used the link from Farrukh's comment a
stackoverflow answer
Code is updated to:
#csrf_exempt
def index(request):
if request.method == 'POST':
form = ExtractForm(request.POST, request.FILES)
if form.is_valid():
res = QueryManager.processRequest(request.user, form.cleaned_data)
format, imgstr = data.split(';base64,')
ext = format.split('/')[-1]
data = ContentFile(base64.b64decode(imgstr), name='temp.' + ext)
filetext = data.read()
filetext contains the string I need from the file.