Publish JSON for Python CGI

I have Apache2 and Python installed.

I have a problem. I have two pages.

One Python page and another Html page with jQuery

Can someone please tell me how can I get my ajax mail to work correctly.

<html> <head> </head> <body> <script> $(function() { alert('Im going to start processing'); $.ajax({ url: "saveList.py", type: "post", data: {'param':{"hello":"world"}}, dataType: "application/json", success : function(response) { alert(response); } }); }); </script> </body> </html> 

And Python code

 import sys import json def index(req): result = {'success':'true','message':'The Command Completed Successfully'}; data = sys.stdin.read(); myjson = json.loads(data); return str(myjson); 
+8
jquery python html ajax
source share
2 answers

OK, go to the updated question.

First, you must pass the Ajax data property in a row representation. Then, since you are mixing the dataType and contentType , change the dataType to "json" :

 $.ajax({ url: "saveList.py", type: "post", data: JSON.stringify({'param':{"hello":"world"}}), dataType: "json", success: function(response) { alert(response); } }); 

Finally, slightly modify your code to work with the JSON request as follows:

 #!/usr/bin/python import sys, json result = {'success':'true','message':'The Command Completed Successfully'}; myjson = json.load(sys.stdin) # Do something with 'myjson' object print 'Content-Type: application/json\n\n' print json.dumps(result) # or "json.dump(result, sys.stdout)" 

As a result, in the success handler of the Ajax request, you get an object with the success and message properties.

+9
source share

You should read json data as follows:

 #!/usr/bin/env python3 import os import sys import json content_len = int(os.environ["CONTENT_LENGTH"]) req_body = sys.stdin.read(content_len) my_dict = json.loads(req_body) 

With the following code, you may run into problems:

  myjson = json.load(sys.stdin) 

or written less succinctly:

 requ_body = sys.stdin.read() my_dict = json.load(requ_body) 

This works for me when my cgi script is on the apache server, but you cannot count on what works at all - as I found out when my cgi script was on another server. According to cgi specification:

 RFC 3875 CGI Version 1.1 October 2004 4.2. Request Message-Body Request data is accessed by the script in a system-defined method; unless defined otherwise, this will be by reading the 'standard input' file descriptor or file handle. Request-Data = [ request-body ] [ extension-data ] request-body = <CONTENT_LENGTH>OCTET extension-data = *OCTET A request-body is supplied with the request if the CONTENT_LENGTH is not NULL. The server MUST make at least that many bytes available for the script to read. The server MAY signal an end-of-file condition after CONTENT_LENGTH bytes have been read or it MAY supply extension data. Therefore, the script MUST NOT attempt to read more than CONTENT_LENGTH bytes, even if more data is available. However, it is not obliged to read any of the data. 

Key line:

The script SHOULD not try to read more than the CONTENT_LENGTH bytes, even if more data is available.

Apparently, apache sends the eof signal to the cgi script immediately after sending the request body to the cgi script, which returns sys.stdin.read() . But according to the cgi specification, the server is not required to send an eof signal after the request body, and I found that my cgi script was hanging on sys.stdin.read() - when my script was on another server, which ultimately caused a time error out.

Therefore, to read in json data in general, you must do this:

 content_len = int(os.environ["CONTENT_LENGTH"]) req_body = sys.stdin.read(content_len) my_dict = json.loads(req_body) 

The server sets up a bunch of environment variables for cgi scripts that contain header information, one of which is CONTENT_LENGTH.

This is what the failed curl request looked like when I used myjson = json.load(sys.stdin) :

 -v verbose output -H specify one header --data implicitly specifies a POST request Note that curl automatically calculates a Content-Length header for you. 

 ~$ curl -v \ > -H 'Content-Type: application/json' \ > --data '{"a": 1, "b": 2}' \ > http://localhost:65451/cgi-bin/1.py * Trying ::1... * TCP_NODELAY set * Connection failed * connect to ::1 port 65451 failed: Connection refused * Trying 127.0.0.1... * TCP_NODELAY set * Connected to localhost (127.0.0.1) port 65451 (#0) > POST /cgi-bin/1.py HTTP/1.1 > Host: localhost:65451 > User-Agent: curl/7.58.0 > Accept: */* > Content-Type: application/json > Content-Length: 16 > * upload completely sent off: 16 out of 16 bytes === hung here for about 5 seconds ==== < HTTP/1.1 504 Gateway Time-out < Date: Thu, 08 Mar 2018 17:53:30 GMT < Content-Type: text/html < Server: inets/6.4.5 * no chunk, no close, no size. Assume close to signal end < * Closing connection 0 
0
source share

All Articles