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?.
Related
I have a JQuery event that, when a link is clicked, an AJAX POST request is sent to a Django function. There I print the recieved url and do other stuff with it. However, when it is printed (by Django) some characters in the url are changed.
The specific url this happened with was :
https://www.catholicleague.org/05press_releases/quarter%204/051110_put_on_notice.htm
Which was printed as :
https://www.catholicleague.org/05press_releases/quarter+4/051110_put_on_notice.htm
Where %20 was changed to +
Here is the AJAX and Django code:
$("a").on("click", function(e){
e.preventDefault();
if(e.target.href){
let clicked_source = e.target.href;
let csrf_tok = parent.document.getElementById("csrf_tok").value;
$.ajax({
url: "/change_origin/",
data: JSON.stringify({"clicked_source":clicked_source}),
type: "POST",
beforeSend: function (xhr, settings) { xhr.setRequestHeader("X-CSRFToken", csrf_tok );},
success: function(response) {
console.log(response.msg)
},
error:function(error) { console.log(error); }
});
}
});
def change_origin(request):
if request.method == 'POST':
received = ast.literal_eval(request.body.decode())
print(received)
clicked_source_url = received['clicked_source']
return JsonResponse({'msg': "ok"})
Where decode is used as the JSON object is received in Python as a byte-like object. And ast is used to turn the string representation of the object to an actual object (or dict) for access.
I need either:
1) A way to just send a string from Ajax to Django
2) A better way to deal with the received object as I believe using .decode() might be the one causing this issue.
EDIT: The link is the second link in the "origin" part of this article
https://www.snopes.com/fact-check/an-unmerried-woman/
I am trying to understand how the Ajax call works.
I am sending a Json object to a bottle python webservice as an URL.
$.ajax({
type: "POST",
data: {"jstring": JSON.stringify(output)},
url: "http://localhost:8080/salesvolume" ,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data){
$('#container').highcharts(data);
},
error: function() {
alert("Something is not OK")
},
});
The above snippet is my Ajax Call. output is the Json object that I intend to send to the server.
#app.post('/salesvolume')
def salesvolume(db):
jsonstring = request.forms.get('jstring')
_jsonparams = json.loads(jsonstring)
_studios = _jsonparams.Studios
ret = `Some Json`
return json.loads(ret)
app.run(server='paste', host='localhost', port=8080, debug=True, reloader=True)
And this is my Web Service code snippet.
I get a Status Code: HTTP/1.0 500 Internal Server Error
I have been following the Bottle and Jquery documentations but Im just not able to crack this.
Any help on this will be really greatful.
Consider the following things:
1) In JS, change the url to simply: /salesvolume.
2) In Python, remove the arg - db from the salesvolume function definition. Or else you might get this err (a 500 error):
TypeError: salesvolume() takes exactly 1 argument (0 given)
<myServerIP> - - [30/Jul/2015 13:31:27] "POST /salesvolume HTTP/1.1" 500 1328
3) Check indentation. Python it is! I guess
ret = Some Json and
return json.loads(ret) needs indentation (they should be inside the salesvolume function)
I wrote this similar stuff and it seems to be working:
Python:
from bottle import *
import json, requests
#route('/')
def atHome():
return template('index')
#route('/salesvolume', method="POST")
def salesvolume():
#your processings here...
ret = '{"key":"val"}'
return json.loads(ret)
run(host='0.0.0.0', port=8093, debug=True, reloader=True)
index.tpl and JS:
<html>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<body>
<button onclick=ajaxF()>click</button>
</body>
<script>
function ajaxF(){
$.ajax({
type: "POST",
data: {"jstring": JSON.stringify("blah")},
url: "/salesvolume" ,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data){
console.log('success');
console.log(data)
},
error: function() {
console.log("Something is not OK");
},
});
}
</script>
</html>
Hope it helps!
The following code worked for me in an app using bottle (sends some data to python and dispatches some data back as JSON from python to js):
js:
$.post('/getData', {myStringInput:dataToSendtoBottle}, function(data){
var myJson = JSON.parse(data) //myOutput is dispatched back to js as JSON
});
python:
#route('/getData', method='POST')
def getData():
myDataReceivedfromJs = request.forms.get('myStringIput')
if myDataReceivedfromJs:
myStringOutput = 'OK'
myOutput = json.dumps(myStringOutput)
return myOutput
I am trying to do a JSON post to my Bottle server.
from bottle import request, route, run
#route('/feedback', method='POST')
def feedback():
data = request.json
print data
run(host='localhost',port=8080)
In the client side, I have
$('#user_feedback').submit(function() {
var feedback = {"id": 1}
$.ajax({
type: "POST",
url: "http://localhost:8080/feedback",
data: feedback
});
return false;
});
I am returning false here because I don't want the page to be redirected.
However, the data I received in my Bottle server is always None when printed out.
Please help. Thank you.
request.json expects the content type of the request to be application/json .
So to make it work, you should set the contentType property of your request to application/json and stringify your data :
$.ajax({
type:"POST",
contentType: "application/json",
url:"/feedback",
data: JSON.stringify(feedback)
});
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"
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"