【问题标题】:Python Redirect not workingPython重定向不起作用
【发布时间】:2015-08-19 02:36:53
【问题描述】:

我正在尝试将用户重定向到我的主页。它假设就像

一样简单
print "Location:http://localhost:8000/index.html"
print ""

由于某种原因,这不起作用。我在 Kali Linux 上运行 CGIHTTPServer。我正在使用 Python 2.7.3 当我尝试运行脚本时,它只是打印出来

Location:http://localhost:8000/index.html

我也尝试过使用 127.0.0.1 而不是 localhost。它也不起作用。这是我正在尝试运行的 CGI 脚本

#!/usr/bin/python
import MySQLdb,cgi, os, sys
db=MySQLdb.connect(host="localhost", user="root", passwd="", db="test")
flag=False
query = db.cursor()
sys.stdout.write("Content-type: text/html\r\n\r\n")
sys.stdout.write("")
sys.stdout.write("<html><body>")
form = cgi.FieldStorage()
name = form.getvalue('temp')
passwd = form.getvalue('temp2')

if(query.execute("select * from cred where uname='"+name+"' and pass='"+passwd+"'")):
    db.commit()
    sys.stdout.write("Hello "+name)

else:
    db.commit()
    flag=True
sys.stdout.write("</body></html>")

if(flag == True):
    print "Location:http://localhost:8000/"
    print ""

【问题讨论】:

    标签: python cgi


    【解决方案1】:

    正如接受的答案所述,您需要 Status: 302 FoundStatus: 301 Moved Permanently 标头以及 Location 标头才能正确执行重定向。

    此外,Python 内置的 CGIHTTPServer “无法执行重定向(HTTP 代码 302),因为代码 200(脚本输出如下)在 CGI 脚本执行之前发送。这会抢占状态代码。” (https://docs.python.org/2/library/cgihttpserver.html)

    不幸的是,在 Python 3 中也是如此。(https://docs.python.org/3/library/http.server.html#http.server.CGIHTTPRequestHandler)

    有一张关于它的票 (http://bugs.python.org/issue10487) 但截至目前,无法使用 Status 标头。这应该不是其他 CGI 服务器的问题。

    【讨论】:

    • 关于 CGIHTTPServer 不支持重定向的好信息,如果我没有阅读您的答案,我可能会花几个小时挠头。
    【解决方案2】:

    你有两个问题:

    1. 总是在开头写上Content-Type 标头加上额外的换行符。你现在已经完成了所有的标题,你不能再添加更多了。

      在您重定向时写入这些标头。

    2. Location 标头仅用于重定向,即状态 30x HTTP 响应。您需要添加一个 Status: 标头来向 Web 服务器发出信号,以响应 200 以外的状态。

    调整您的代码以解决这些问题:

    #!/usr/bin/python
    import cgitb
    cgitb.enable()
    
    import MySQLdb, cgi, os, sys
    
    db = MySQLdb.connect(host="localhost", user="root", passwd="", db="test")
    
    form = cgi.FieldStorage()
    name = form.getvalue('temp')
    passwd = form.getvalue('temp2')
    
    with db as query:
        query.execute("select * from cred where uname=%s and %s", (name, passwd))
        result = query.fetchone()
        
    if result is None:
        # no such user, redirect
        print 'Status: 302 Found'
        print 'Location: http://localhost:8000/'
        print
    
    else:
        print 'Content-type: text/html'
        print
        print '<html><body>Hello {}</body></html>'.format(name)
    

    请注意,我稍微修改了代码以使用一些最佳实践:

    1. 从不使用字符串插值将用户信息放入 SQL 查询中。这样你就会受到 SQL 注入攻击的打击。使用 SQL 参数让数据库驱动程序为您转义值。

    2. 您可以将连接用作上下文管理器来自动提交。

    3. 我使用字符串格式来生成 HTML 输出。

    【讨论】:

    • 我按照您的要求进行了所有更改,但还没有工作。我的服务器日志没有错误,显示的网页只是空白。更不用说它没有重定向。
    • @user3905719:在这种情况下,您的 Web 服务器似乎不支持 Status: 标头;这违反了 CGI 协议。您可以添加 Content-type: text/html 标头和 print '&lt;html&gt;&lt;head&gt;&lt;meta http-equiv="refresh" content="0;url=http://localhost:8000" /&gt;&lt;/head&gt;&lt;/html&gt;' 行以添加 HTML 正文,指示浏览器重定向。
    • @user3905719:在现代浏览器中,您可以使用开发人员工具查看服务器发送的标头;寻找网络标签。
    • 使用了开发者工具。它说状态文本:200。无论如何我添加了另一个标题。现在它工作得很好。谢谢。
    猜你喜欢
    • 2014-01-08
    • 2016-05-24
    • 2021-10-29
    • 1970-01-01
    • 2017-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多