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

 

测试代码:

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>

 

测试结果:

浏览器访问: http://www.client.com:8081/

http GET: hello world.

http POST:

 

奇怪,怎么POST没结果了?用firebug调试了一下,发现是FIREFOX的跨域访问限制问题,会自动将POST请求变成OPTIONS,囧啊,不过GET方式以足够。

PS:tornado.web.asynchronous测试通过。

希望本文对你有用,^_^!

posted @ 2009-11-05 08:51  MK2  阅读(2386)  评论(0)    收藏  举报