2012-05-23 16 views
8

पर JSON पोस्ट करें मुझे Apache2 इंस्टॉल किया गया है और पायथन काम कर रहा है।पायथन सीजीआई

हालांकि मुझे कोई समस्या है। मेरे पास दो पेज हैं

एक एक अजगर पृष्ठ और 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> 

और अजगर कोड

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); 
+0

मुमकिन है, कुछ नहीं होता? कृपया हमें जो समस्याएं आप देखते हैं उन्हें बताएं। –

+0

क्या आप एक JSON या JSON-string पोस्ट कर रहे हैं जो प्रतिशत-एन्कोडेड है? – SuperSaiyan

+0

मुझे बस यह चाहिए कि यह मुझे दिखाता है कि मैंने क्या पोस्ट किया है, इसलिए मुझे एक विचार है कि यह वास्तव में काम करता है। वर्तमान में इसे "शून्य" – TheMonkeyMan

उत्तर

9

ठीक है, के अपने अपडेट किए गए सवाल पर चलें।

सबसे पहले, आपको स्ट्रिंग प्रतिनिधित्व में अजाक्स डेटा प्रॉपर्टी पास करनी चाहिए। फिर, जब से तुम मिश्रण dataType और contentType गुण, बदल dataType मूल्य "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({ 
    url: "saveList.py", 
    type: "post", 
    data: JSON.stringify({'param':{"hello":"world"}}), 
    dataType: "json", 
    success: function(response) { 
     alert(response); 
    } 
}); 

अंत में, एक सा JSON अनुरोध के साथ काम करने के लिए इस प्रकार संशोधित अपने कोड अजाक्स अनुरोध के success हैंडलर आपको success और message गुणों के साथ ऑब्जेक्ट प्राप्त होगा।

+1

वह 'एप्लिकेशन/जेसन' पोस्ट कर रहा है, न कि 'एप्लिकेशन/एक्स-www-form-urlencoded'। Stdin से पढ़ने का उनका तरीका सही है (आईएमओ)। मुझे लगता है कि समस्या कहीं और है। – SuperSaiyan

+0

@ थ्रस्टमास्टर आप किस बारे में बात कर रहे हैं? डिफ़ॉल्ट सामग्री * मानक * अजाक्स अनुरोध के लिए टाइप करें exaclty 'application/x-www-form-urlencoded' है। आपको कुछ और उपयोग करने की आवश्यकता क्यों है? – VisioN

+1

ओपी (उसके कोड से) HTTP के शरीर में JSON-string के साथ एक HTTP/POST कर रहा है। सामग्री-प्रकार 'एप्लिकेशन/जेसन' होगा जिसे '$ .ajax ({contentType: "application/json"}, ...) का उपयोग करके सेट करने की आवश्यकता होगी। आपने जो सुझाव दिया है, वह JSON स्ट्रिंग को url-encode करना है, जो, आईएमओ, ओपी नहीं कर रहा है (क्योंकि वह उस के लिए सर्वर-साइड पर stdin से सही ढंग से पढ़ रहा है) – SuperSaiyan

0

आप इस तरह 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) 

कि मेरे लिए काम करता है जब मेरी सीजीआई स्क्रिप्ट apache सर्वर पर है, लेकिन आप सामान्य रूप से उस काम पर भरोसा नहीं कर सकते - जैसा कि मैंने पाया कि मेरी सीजीआई स्क्रिप्ट किसी अन्य सर्वर पर थी। 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 बाइट्स से अधिक को पढ़ने के लिए, भले ही अधिक डेटा उपलब्ध है प्रयास नहीं करना चाहिए।

जाहिर है, apache तुरंत cgi स्क्रिप्ट है, जो sys.stdin.read() का कारण बनता है वापस जाने के लिए करने के लिए अनुरोध शरीर भेजने के बाद cgi स्क्रिप्ट के लिए एक EOF संकेत भेजता है। लेकिन सीजीआई स्पेक के मुताबिक, अनुरोध के शरीर के बाद एक सर्वर को ईफ सिग्नल भेजने की आवश्यकता नहीं है, और मैंने पाया कि मेरी सीजीआई स्क्रिप्ट sys.stdin.read() पर लटक रही थी - जब मेरी स्क्रिप्ट किसी अन्य सर्वर पर थी, जिसने अंततः एक टाइमआउट त्रुटि।

इसलिए, सामान्य स्थिति में json डेटा में पढ़ने के लिए है, तो आप इस करना चाहिए:

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

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

सर्वर CGI स्क्रिप्ट है, जो जानकारी शीर्षक शामिल, के लिए वातावरण चर का एक समूह सेट जिनमें से एक CONTENT_LENGTH है

यहाँ एक असफल कर्ल अनुरोध की तरह जब मैं 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 
संबंधित मुद्दे