12

Apache2がインストールされ、Pythonが機能しています。

私は問題を抱えています。2ページあります。

1つはPythonページで、もう1つはJQueryを使用したHTMLページです。

誰かが私のajax投稿を正しく機能させる方法を教えてもらえますか?

<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>

そしてPythonコード

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);
4

3 に答える 3

14

OK、更新された質問に移りましょう。

まず、文字列表現でAjaxデータプロパティを渡す必要があります。dataType次に、contentTypeプロパティを混在させるため、dataType値を"json"次のように変更します。

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

最後に、次のようにJSONリクエストを処理するようにコードを少し変更します。

#!/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)"

その結果、Ajaxリクエストのハンドラーで、プロパティsuccessを持つオブジェクトを受け取ります。successmessage

于 2012-05-23T11:20:00.287 に答える
7

次のようにjsonデータを読み取る必要があります。

#!/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)

次のコードを使用すると、問題が発生する可能性があります。

 myjson = json.load(sys.stdin)

またはあまり簡潔に書かれていません:

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

私のcgiスクリプトがサーバー上にある場合、それ私にとってはapacheうまくいきますが、私のcgiスクリプトが別のサーバー上にあるときにわかったように、一般的にはそれが機能することを期待することはできません。cgi仕様によると:

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.

キーラインは次のとおりです。

より多くのデータが利用可能であっても、スクリプトはCONTENT_LENGTHバイトを超えて読み取ろうとしてはなりません(MUSTNOT)。

どうやら、apacheリクエスト本文をcgiスクリプトに送信した直後に、eofシグナルをcgiスクリプトに送信します。これによりsys.stdin.read()、が返されます。しかし、cgi仕様によると、サーバーはリクエストの本文の後にeofシグナルを送信する必要はなくsys.stdin.read()、スクリプトが別のサーバー上にあるときにcgiスクリプトがハングしていることがわかり、最終的にタイムアウトエラーが発生しました。

したがって、一般的なケースでjsonデータを読み込むには、次のようにする必要があります。

content_len = int(os.environ["CONTENT_LENGTH"])

req_body = sys.stdin.read(content_len)
my_dict = json.loads(req_body)

サーバーは、ヘッダー情報を含むcgiスクリプトの一連の環境変数を設定します。そのうちの1つはCONTENT_LENGTHです。

使用したときに失敗したcurlリクエストは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
于 2018-03-09T05:58:47.977 に答える
1

素晴らしい@7studの答えに少し追加すると、バッファから読み取ることで修正したUnicodeを読み取るときに、コンテンツの長さに問題がありました。

content_length = int(os.environ["CONTENT_LENGTH"])
data = sys.stdin.buffer.read(content_length).decode('utf-8')
于 2021-04-06T09:50:48.857 に答える