Python重定向无效
我想把用户重定向到我的主页。这个操作应该很简单,像这样:
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 ""
2 个回答
根据被接受的答案,你需要使用 Status: 302 Found
或 Status: 301 Moved Permanently
这样的状态头,并且还要加上 Location
头,才能正确地进行重定向。
另外,Python 内置的 CGIHTTPServer 无法执行重定向(HTTP 代码 302),因为在执行 CGI 脚本之前,它会先发送代码 200(表示脚本输出开始)。这就导致状态码被提前发送了。 (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),但目前为止,还是没有办法使用状态头。其他的 CGI 服务器应该不会有这个问题。
你这里有两个问题:
你总是在开始时写
Content-Type
头部加上额外的换行。这样一来,你就完成了所有的头部,之后就不能再添加更多了。只有在不进行重定向的时候,才写这些头部。
Location
头部只用于重定向,也就是状态为30x的HTTP响应。你需要添加一个Status:
头部,告诉网络服务器返回一个不是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)
注意,我对代码做了一些修改,采用了一些最佳实践:
绝对不要使用字符串插值把用户信息放进SQL查询里。这样会遭到SQL注入攻击。应该使用SQL参数,让数据库驱动程序帮你处理这些值。
你可以把连接当作上下文管理器来自动提交。
我使用字符串格式化来生成HTML输出。