Tornado JSONPHandler, 支持JSONP的请求封装
由于JSONP强大的跨域访问功能,发现tornado没有对jsonp的默认支持,还好tornado是开源的,就简单实现了一个JSONPHandler,对一切JSONP请求进行封装。
JSONPHandler实现代码如下:
只需要对finish方法进行简单封装,即可
#!/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
# -*- 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
测试代码:
main.py

#!/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>
<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>
测试结果:
浏览器访问: http://www.client.com:8081/
http GET: hello world.
http POST:
奇怪,怎么POST没结果了?用firebug调试了一下,发现是FIREFOX的跨域访问限制问题,会自动将POST请求变成OPTIONS,囧啊,不过GET方式以足够。
PS:tornado.web.asynchronous测试通过。
希望本文对你有用,^_^!