使用 WSGI 将用户重定向到 url(无框架) [英] Redirect a user to url with WSGI (no framework)

查看:67
本文介绍了使用 WSGI 将用户重定向到 url(无框架)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 python 的 WSGI 开发一个小型 Web 应用程序.例如,如果用户选择 Google,他们将被重定向到 google.com,如果他们选择 Facebook,他们将被重定向到 facebook.com 等.

I am trying to develop a small web application using python's WSGI. For example, if a user chooses Google they would be redirected to google.com, if they chose Facebook they'd be redirected to facebook.com, etc.

from wsgiref.simple_server import make_server
from cgi import parse_qs, escape

main_html = """
<html>
<head><title> Welcome to redirection test page </title> </head>
<body>
    <form method="get" action='/visit'>
        <input type=radio name='site' value=google> Google
        <input type=radio name='site' value=facebook> Facebook
        <input type=submit value=submit>
    </form>
</body>
</html>
"""


def main(environ, start_response):

    response_body = main_html
    print type(response_body)   
    status = '200 OK'

    response_headers = [
                        ('Content-Type','text/html'),
                        ('Content-Length', str(len(response_body)))
                       ]


    start_response(status, response_headers)
    return [response_body]


def visit(environ, start_response):
    qs = parse_qs(environ['QUERY_STRING'])
    dest = qs.ge('site')[0]
    if dest == 'google':
        start_response('301 Moved Permanently', [('Location','http://google.com')])
    else:
        start_response('301 Moved Permanently', [('Location','http://facebook.com')])

    return [1]


def app(environ, start_response):
    if environ['PATH_INFO'] == '/':
        return main(environ, start_response)
    elif environ['PATH_INFO'] == '/visit':
        return visit(environ, start_response)

httpd =  make_server('192.168.48.128',8052, app)
print 'Serving on port 8052'
httpd.serve_forever()

但是,当我运行此代码时,出现以下错误:

However, when I run this code, I get the following error:

Traceback (most recent call last):
  File "/usr/lib/python2.7/wsgiref/handlers.py", line 86, in run
    self.finish_response()
  File "/usr/lib/python2.7/wsgiref/handlers.py", line 131, in finish_response
    self.close()
  File "/usr/lib/python2.7/wsgiref/simple_server.py", line 33, in close
    self.status.split(' ',1)[0], self.bytes_sent
AttributeError: 'NoneType' object has no attribute 'split'

推荐答案

您有两个问题,都在 visit() 中.第一个是打字错误,第二个是未能遵守 WSGI 规范

You have two problems, both within visit(). The first is a typo, and the second is a failure to adhere to the WSGI specification

def visit(environ, start_response):
    qs = parse_qs(environ['QUERY_STRING'])
    dest = qs.ge('site')[0]
    if dest == 'google':
        start_response('301 Moved Permanently', [('Location','http://google.com')])
    else:
        start_response('301 Moved Permanently', [('Location','http://facebook.com')])

    return [1]

查看 dest = qs.ge('site')[0] 行.qs 只是一个字典,没有方法ge,只有get.此外,cgi.parse_qs 已弃用 - 使用 urlparse.parse_qs() 代替.修复这会给我们带来一个新错误(我的地址是 127.0.0.1,因为我只是从 localhost 运行它):

Look at the line dest = qs.ge('site')[0]. qs is just a dictionary, and doesn't have a method ge, just get. Furthermore, cgi.parse_qs is deprecated - use urlparse.parse_qs() instead. Fixing that gets us a new error (my address is 127.0.0.1 because I just ran it off of localhost):

127.0.0.1 - - [05/Feb/2015 16:45:17] "GET /visit?site=facebook HTTP/1.1" 302 0 
Traceback (most recent call last):
  File "C:\Python27\lib\wsgiref\handlers.py", line 86, in run
    self.finish_response()
  File "C:\Python27\lib\wsgiref\handlers.py", line 128, in finish_response
    self.write(data)
  File "C:\Python27\lib\wsgiref\handlers.py", line 204, in write
    assert type(data) is StringType, "write() argument must be string"
AssertionError: write() argument must be string

这告诉我们某些东西应该是一个字符串,但不是.再次查看 visit(),在返回行,发现了问题.您返回的是 [1] 而不是 ['1'].修复该错误使一切正常.您会发现此行为记录在 PEP 333

This tells us that something should be a string, but isn't. Looking again at visit(), at the return line, reveals the problem. You're returning [1] instead of ['1']. Fixing that error makes everything work fine. You'll find that this behavior is documented in PEP 333

start_response 可调用对象必须返回一个 write(body_data) 可调用对象,它采用一个位置参数:一个字符串作为 HTTP 响应正文的一部分写入.

The start_response callable must return a write(body_data) callable that takes one positional parameter: a string to be written as part of the HTTP response body.

最后,根据 这个答案,您可能应该使用 '302 Found' status 而不是 '301 Moved Permanently' 用于重定向,但无论哪种方式都有效.

Lastly, as per this answer, you should probably be using a '302 Found' status instead of '301 Moved Permanently' for a redirect, but it works either way.

用这个替换函数应该可以解决您的问题:

Replacing the function with this should fix your issue:

def visit(environ, start_response):
    qs = parse_qs(environ['QUERY_STRING'])
    dest = qs.get('site')[0]
    if dest == 'google':
        start_response('302 Found', [('Location','http://google.com')])
    else:
        start_response('302 Found', [('Location','http://facebook.com')])

    return ['1']

这篇关于使用 WSGI 将用户重定向到 url(无框架)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆