IE7 throws "parseerror" parsing JSON using jQuery - python

IE7 throws an exception: "jquery: parseerror" when running the following code. It works in all other browsers I've tested (Firefox, Opera, Chrome, Chromium).
Script:
function check(){
$("#form").ajaxSubmit({
url: "/send-file",
dataType: "json",
success:
function(answer){
$("#result").html(answer.msg);
},
error:
function(jqXHR, textStatus, errorThrown){
alert(textStatus);
}
});
return false;
}
The server script(controller of Pylons):
#jsonify
def sendFile(self):
response.content_type = "text/plain"
response.cache_control = 'no-cache'
response.pragma = "no-cache, must-revalidate"
response.expires = "-1"
data = dict(msg = '<h1 id="sd">ffffffffff</h1> \
<p>ddddd</p> link' )
return data

the problem seems to be in the jQuery plugin for uploading files using hidden frame. If it is the plugin, than it contains an error (if i recall correctly it reads the contents of the json from the body tag). I wanted to chat on the issue with the author, but the facebook comments in his blog raised an exception. As result, I slightly fixed the plugin locally to read the whole server result.
Unfortunatelly, I currently don't have access the hacked version.

instead if
response.content_type = "text/plain"
try
response.content_type = "application/json"

Related

send metatags through Google Cloud Signed URL with Django

I'm using signed url to get or post/put video fileq on my google storage. My modules refers on signed_url V4 and it's working quite well.
I wanted to add some metadata tags to my requests in order to manage more efficiently the charges related to GCS. But since I added those headers, the requests failed returning a cors policy error : (I have shortened the signature in the block above to make it more readable)
Access to XMLHttpRequest at 'https://test-dev-slotll.storage.googleapis.com/uploads/dave/FR/eaa678c9/2020/9/785f/f45d3d82-785f_full.mp4?X-
Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=dev-storage%40brilliant-tower-264412.iam.gserviceaccount.com%2F20200926%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20200926T093102Z&X-Goog-Expires=3600&X-Goog-SignedHeaders=host%3Bx-goog-meta-account&x-goog-signature=6fbb27e[...]bd0891d21' from origin 'http://localhost:8000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
and the detailed message:
<Error>
<Code>MalformedSecurityHeader</Code>
<Message>Your request has a malformed header.</Message>
<ParameterName>x-goog-meta-account</ParameterName>
<Details>Header was included in signedheaders, but not in the request.</Details>
</Error>
The cors are conigured to allow almost everything on my bucket :
[{"maxAgeSeconds": 3600, "method": ["*"], "origin": ["*"], "responseHeader": ["*"]}]
and here is the Python/Django function
def _get_signed_url(self, http_method="GET"):
"""' create a signed url with google storage
create a 'GET' request by default,
add method='w' or 'put' to create a 'PUT' request
get_signed_url('w')->PUT / get_signed_url()->GET
"""
if http_method.lower() in ["w", "put", "post"]:
http_method = "PUT"
else:
http_method = "GET"
signed_url = generate_signed_url(
settings.GS_BUCKET_NAME,
self.file.name,
subresource=None,
expiration=3600,
http_method=http_method,
query_parameters=None,
headers={'x-goog-meta-language':'french','x-goog-meta-account':'david',},
)
return signed_url
As I wrote it above, method get_signed_url() is copied from signed_url V4
if i replace headers = {'x-goog-meta-language':'french','x-goog-meta-account':'david',},
by hearders = {} or headers = None (as it was previously, it works fine
last, when I click on the link given by the signed-url, I got an error message:
The signed url as well as blob uploading or downloading are working fine without the headers for months but I do not see why the server is responding that the header meta tags are malformed...
I will appreciate any help
thanks !
I was getting the same error message when I was performing a GET request on the pre-signed urls from GCP. Adding the content-type: "application/octet-stream" solved it for me.
ajaxCall_getFile = $.ajax({
xhr: function() {
var xhr = new window.XMLHttpRequest();
return xhr;
},
type: 'GET',
url: <PRE-SIGNED URL>,
contentType: "application/octet-stream",
processData: false,
success: function(file_data){
alert("file downloaded");
},
error: function(err) {
alert('Download failed, please try again.');
}
});
As #Sideshowbarker suggests it in his comments, the problem came from the client.
The signed url was used to send files to storage through ajax but no custom header were added to the ajax.
By specifying the headers in the ajax, the PUT request of a signed url with custom metadata works well.
function ajaxSendToStorage(uuid, url) {
// Sending ONE file to storage
var file = getFileById(uuid);
$.ajax({
method: "PUT",
contentType: file.type,
processData: false,
dataType: "xml",
crossDomain: true,
data: file,
url: url,
headers: {"x-goog-meta-account":"david","x-goog-meta-language": "fr"},
success: function() {},
complete: function() {},
});
}

I am getting jQuery Jtable error while fetching data from the python server

I have a jQuery Jtable in the front end and I am using python flask in my server.
I used python flask to fetch data from the MYSQL server which I can view in the JSON format in my browser but, unfortunately I couldn't able to make the JSON data into the Jtable.
My front end jQuery Jtable is
$('#eventsummary').jtable({
actions: {
listAction: function (postData) {
return $.Deferred(function ($dfd) {
$.ajax({
url: '/backend/groupdata',
type: 'GET',
data: postData,
success: function (data) {
$dfd.resolve(data);
console.log("loading ");
},
});
});
}
},
fields: {
irs_type: {
title: "Date & Time",
list: true,
}
}
});
$('#eventsummary').jtable('load');
and this is the error I am getting
I am also able to view my console.log code in the browser, with no error in the console.
Can someone please help me with this
Thanks,
I achieved this by using python jsonify to add my json data to the front end Jtable.
for result in data:
json_data.append(dict(zip(row_headers,result)))
return jsonify(
{
'Result': "OK",
'Records': json_data,
}
)
Thanks
The output you are seeing is the standard jTable application error. Your listAction has passed the server response to jTable, so there is no communications error.
When the json response does NOT contain Result = 'OK' it displays the application error dialog, and shows the json Message in the dialog.
The very fact that the error dialog appears means jTable is not seeing Result = 'OK' in your server response. Look for that first, if you are still stuck please post your json response. The dialog is blank because there is no error message or jTable can't see it.

Request.files object is empty on flask server when uploaded using ng-file-upload

I am using ng-file-upload to upload a xls or xlsx file, below is my html code
<div ngf-drop ngf-select ngf-change="checkFile($invalidFiles);" ngf-model-invalid="invalidFiles" ng-model="file" class="center" ngf-drag-over-class="'dragover'" ngf-pattern="'.xls,.xlsx'">
<button class="some-class" ng-click="upload(file)"></button>
Angular controller:
$scope.upload = function (file) {
if (file) {
var upload = Upload.upload({
url: API.url('upload'),
data: {
file: file
},
headers:{ // tried passing different headers as well
"Content-Type":"multipart/form-data"
}
});
upload.then(function (resp) {
//Some Operation
}, null, function (evt) {
//Some Operation
});
}
};
Flask server:
def upload(self):
params = self.get_params(request)
file = request.files['file'] ###This object is empty.
result = self._upload_file(file)
return "Dummy"
I followed this documentation for server side.
I think the problem is from client side, may be I am sending some bad request as flask server is throwing 400. So I have tried by sending 'multipart/form-data' headers but no luck and also by sending Form data explicitly.
I have also looked for few solutions like sol-1.
I didn't find anything which could solve my problem in the ng-file-upload doc as well.
If required I can send the request headers as well.
I might be missing very tiny part, can someone please point me out that.
There is default value for headers which is already in post request. Adding "Content-Type":"multipart/form-data" is just overriding that. Try it without that.

'Request' object has no attribute 'json'

I've run the following command in the terminal to verify my current installation of cherryPy
python -c "import cherrypy;print cherrypy.__version__"
3.3.0
However, the following code results in error:
#cherrypy.expose
#cherrypy.tools.json_in()
def observe(self, urlParam1=None):
print cherrypy.request.json
return ""
When running this I get the following error:
File "C:\Anaconda\lib\site-packages\cherrypy\__init__.py", line 224, in __getattr__
return getattr(child, name)
AttributeError: 'Request' object has no attribute 'json'
EDIT:
This is how I'm sending the request:
var insertJSON = JSON.stringify(insertObj);
$.ajax({
type : "POST",
contentType : "application/json",
url : 'http://10.XX.X.XXX:XXXX/observe',
data : insertJSON,
dataType : "json",
success : function(result) {
alert('observation inserted');
}
});
Edit 2:
I'm doing this all in Eclipse with PyDev. If I control-click on request in cherrypy.request it opens up the file cherypy__init__.py as should be expected. However, if I control-click on json, it doesn't know where the file is.
I've tried uninstalling the library manually - and then redownloading from https://pypi.python.org/pypi/CherryPy/3.2.4 and placing the appropriate folders in C:\Anaconda\Lib\site-packages
The JSON parameter does not exist in the OPTION method, only in the POST.
With CORS, when you POST, you have 2 requests: one is a OPTION, the second is the POST.
Add a simple test in your method:
#cherrypy.expose
#cherrypy.tools.json_out()
#cherrypy.tools.json_in()
def dosomething(self):
result = {"operation": "request", "result": "success"}
if cherrypy.request.method == "POST":
print(cherrypy.request.json)
return result
Are you posting the json object? This code works fine for me.
import cherrypy
class HelloWorld(object):
#cherrypy.expose
#cherrypy.tools.json_in()
def observe(self, urlParam1=None):
print(cherrypy.request.json)
return ""
#cherrypy.expose
def asdf(self):
return """<!DOCTYPE HTML>
<html>
<head>
<script>function Sendjson(){
// code for IE7+, Firefox, Chrome, Opera, Safari
if(window.XMLHttpRequest)
xmlhttp=new XMLHttpRequest();
else// code for IE5
xmlhttp=new ActiveXObject('Microsoft.XMLHTTP');
xmlhttp.open("POST","/observe", true);
xmlhttp.setRequestHeader('Content-Type', 'application/json');
xmlhttp.send(JSON.stringify(({name:"Bob"})));
}
</script>
</head>
<body onload="Sendjson();">
</body>
</html>"""
cherrypy.quickstart(HelloWorld())
Hope this helps!
You might run into this issue if you are missing json_in()
#cherrypy.tools.json_in()
def POST(self, ...):
...
Well, it's true, you are sending the POST data as JSON, not as typical form-encoded data, and thus you never set the key json. You can do
$.ajax({
type : "POST",
url : 'http://10.XX.X.XXX:XXXX/observe',
data : {json: insertJSON},
// ^^^^
success : function(result) {
alert('observation inserted');
}
});
Or if you really want to send the data JSON encoded, you have to access the raw request body. See How to receive JSON in a POST request in CherryPy?.

how to open a PDF file while returning the file in AJAX request success response

I get 2 dates, start and end date, via AJAX. I process the data b/w those 2 dates, generate a report and then returns an HttpResponse. The PDF report is now saved in my main project directory. Now I get a response back in AJAX. So, now how should I process the response in the success function, sent back from the sever and open a PDF file.
Thanks.
jQuery
$(function() {
$("#report_submit").click(function(){
$.ajax({
type : "POST",
url: "/reports/",
data : { 'start_date' : $("#startDate").val() , 'end_date' : $("#endDate").val() },
success : function(result){
},
error : function(result){
}
});
});
});
Django view code
def generate_report(request):
ctx = {}
if request.is_ajax():
if request.POST.has_key('start_date'):
start_date = datetime.strptime(request.POST[ 'start_date'] , '%m/%d/%Y')
end_date = datetime.strptime(request.POST[ 'end_date'] , '%m/%d/%Y')
......
# PDF GENERATED in MAIN PROJECT DIRECTORY
with open(os.path.join(os.path.dirname(__file__),'../../../../gui','Report.pdf')) as pdf:
response = HttpResponse(pdf.read(), content_type='application/pdf')
response['Content-Disposition'] = 'inline;filename=Report.pdf'
return response # so, now when I send a response back, how should I process it in AJAX success function?
pdf.closed
return render(request, 'generate_report/reports.html', ctx)
Don't try and send it in the Ajax response. Instead, get your view to generate a unique URL for the PDF, then get the JS to redirect the browser to that URL:
view:
return HttpResponse(json.dumps({'url': my_url})
JS:
$.ajax({
type : "POST",
dataType: "json",
url: "/reports/",
data : { 'start_date' : $("#startDate").val() , 'end_date' : $("#endDate").val() },
success : function(result){
var url = result['url'];
window.location = url;
},
The simplest solution would be to call window.open(pdf_url) in "success" callback, where pdf_url is the link to your generated pdf report (which you'll need to pass to response).
This problem has been discussed in the following Question... You might need to go for the jquery plugin for file download and please do not forget to set cookie in the response.
PDF file download through XHR Request
You might need to add a javascript file for the file download and also use the folowing code to generate the request to the server.
$.fileDownload(urlll,{
successCallback: function (url)
{
//success code here
},
failCallback: function (html, url)
{
//error code here
}
});
And on the server side while adding the header etc in the response do the following in response object. i.e.
aResponse.addCookie(cookie);
I hope you can solve the issue and can help others as well.. "Dangling Pointer"

Categories

Resources