8

With JS, i send a AJAX post request.

 $.ajax(
        {method:"POST",
        url:"https://my/website/send_data.py",
        data:JSON.stringify(data),
        contentType: 'application/json;charset=UTF-8'

On my Apache2 mod_Python server, I wish for my python file to access data. How can i do this?

def index(req):
    # data = ??

PS: here is how to reproduce the problem. Create testjson.html:

<script type="text/javascript">
xhr = new XMLHttpRequest();
xhr.open("POST", "testjson.py");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function(res) { console.log(xhr.responseText); };
xhr.send(JSON.stringify({'foo': '0', 'bar': '1'}));
</script>

and create testjson.py containing:

from mod_python import apache 

def index(req):
    req.content_type = "application/json"
    req.write("hello")
    data = req.read()
    return apache.OK

Create a .htaccess containing:

AddHandler mod_python .py
PythonHandler mod_python.publisher

Here is the result:

testjson.html:10 POST http://localhost/test_py/testjson.py 501 (Not Implemented)

enter image description here

Basj
  • 41,386
  • 99
  • 383
  • 673
Mitchell van Zuylen
  • 3,905
  • 4
  • 27
  • 64

4 Answers4

3

As pointed by Grisha (mod_python's author) in a private communication, here is the reason why application/json is not supported and outputs a "HTTP 501 Not implemented" error:

https://github.com/grisha/mod_python/blob/master/lib/python/mod_python/util.py#L284

The solution is either to modify this, or to use a regular application/x-www-form-urlencoded encoding, or to use something else than the mod_python.publisher handler.

Example with mod_python and PythonHandler mod_python.publisher:

<script type="text/javascript">
var data = JSON.stringify([1, 2, 3, '&=test', "jkl", {'foo': 'bar'}]); // the data to send
xhr = new XMLHttpRequest();
xhr.open("POST", "testjson.py");
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function(res) { console.log(xhr.responseText); };
xhr.send('data=' + encodeURIComponent(data));
</script>

Server-side:

import json
from mod_python import apache 

def index(req):
    data = json.loads(req.form['data'])
    x = data[-1]['foo']
    req.write("value: " + x)

Output:

value: bar

Success!

Basj
  • 41,386
  • 99
  • 383
  • 673
1

From Mod_python docs:

Client data, such as POST requests, can be read by using the request.read() function.

A K
  • 788
  • 6
  • 17
  • Thank you for this answer, but this does not work in the case of a `application/json` request. See the end of the updated question, are you able to reproduce the problem too? – Basj Feb 20 '20 at 10:33
  • OK. It seems like a configuration problem. – A K Feb 20 '20 at 15:30
  • I tried on another fresh server wtih apache, mod_php, python, etc. and it's the same: HTTP 501 not implemented. When I do a GET it works with HTTP 200. Also OP had the same problem. So at least on 3 machines we were able to reproduce the same error. – Basj Feb 20 '20 at 15:34
  • I answered in a new answer, as it is something else. – A K Feb 20 '20 at 15:40
0

From the Mod Python docs here.

Mod Python Docs

Here you can do, for example to get the data

def index(req):
    data = req.read()

Additional Links : http://vandermerwe.co.nz/?p=9

Prakhar Londhe
  • 1,431
  • 1
  • 12
  • 26
0

As I said, from the new edition it looks like a configuration problem.

First, try to set PythonPath directive.

Secondly, the PythonHandler should be your file, i.e.:

PythonHandler testjson
A K
  • 788
  • 6
  • 17
  • In fact I want to keep `PythonHandler mod_python.publisher` because this allows `example.com/hello.py` to be automatically mapped to running `hello.py`, `example.com/login.py` to be automatically mapped to running `login.py`, instead of hardcoding only one `PythonHandler` and working with only 1 .py file. – Basj Feb 20 '20 at 15:51
  • Look here: https://issues.apache.org/jira/browse/MODPYTHON-29, and here: http://modpython.org/pipermail/mod_python/2007-May/023761.html – A K Feb 20 '20 at 20:51