Due to the powerful cross-origin access function of JSONP, it is found that tornado does not support jsonp by default. Fortunately, tornado is open-source, and thus a JSONPHandler is implemented to encapsulate all JSONP requests.
The JSONPHandler implementation code is as follows:
You only need to encapsulate the finish method.
#! /Usr/bin/python
#-*-Coding: UTF-8 -*-
"Jsonp handler """
From tornado. web import RequestHandler, _ utf8
Class JSONPHandler (RequestHandler ):
CALLBACK = 'jsonp' # define callback argument name
Def finish (self, chunk = None ):
"Finishes this response, ending the HTTP request ."""
Assert not self. _ finished
If chunk: self. write (chunk)
# Get client callback method
Callback = _ utf8 (self. get_argument (self. CALLBACK ))
# Format output with jsonp
Self. _ write_buffer.insert (0, callback + '(')
Self. _ write_buffer.append (')')
# Call base class finish method
Super (JSONPHandler, self). finish () # chunk must be None
Test code:
Main. py
Code
#! /Usr/bin/python
#-*-Coding: UTF-8 -*-
"Web main """
From tornado. httpserver import HTTPServer
From tornado. ioloop import IOLoop
From tornado. web import RequestHandler, Application, authenticated
From tornado. escape import json_encode
From jsonphandler import JSONPHandler
Class MainHandler (RequestHandler ):
Def get (self ):
Self. render ("index.html ")
Class TestJSONP (JSONPHandler ):
Def get (self ):
Self. write (json_encode ({'josnp-get': 'Hello world .'}))
Def post (self ):
Self. write (json_encode ({'josnp-post': 'Hello world .'}))
Settings = {
"Template_path": "templates ",
}
Application = Application ([
(R "/", MainHandler ),
(R "/jsonp/helloword", TestJSONP ),
], ** Settings)
If _ name _ = "_ main __":
Print 'start'
Http_server = HTTPServer (application)
Http_server.listen (8081)
IOLoop. instance (). start ()
Index.html
<Html>
<Head>
<Title> JOSNP test </title>
<Script type = "text/javascript" src = "http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"> </script>
<Script type = "text/javascript">
$ (Function (){
$. GetJSON ('HTTP: // www.server.com: 8081/jsonp/helloword? Jsonp =? ', Function (data ){
('{Get-console'{.html (data ['josnp-get']);
});
$. Post ("http://www.server.com: 8081/jsonp/helloword? Jsonp =? ", Function (data ){
('{Post-console'{.html (data ['josnp-post']);
}, 'Json ');
});
</Script>
</Head>
<Body>
<Div> http GET: <span id = "get-console"> </span> </div>
<Div> http POST: <span id = "post-console"> </span> </div>
</Body>
</Html>
Test results:
Browser access: http://www.client.com: 8081/
Http GET: hello world.
Http POST:
Strange, why does POST fail? I debugged it with firebug and found that it was a cross-origin access restriction problem in FIREFOX. THE POST request will be automatically changed to OPTIONS and conditions, but the GET method is sufficient.
PS: tornado. web. asynchronous passed the test.
Hope this article will be useful to you, ^_^!