【问题标题】:How to return HTTP 303 from python?如何从 python 返回 HTTP 303?
【发布时间】:2016-05-25 19:21:14
【问题描述】:

此问题来自this one

我想要的是能够在用户单击按钮时从我的 python 脚本中返回 HTTP 303 标头。我的脚本非常简单,就输出而言,它打印以下两行:

print "HTTP/1.1 303 See Other\n\n"
print "Location: http://192.168.1.109\n\n"

我也尝试了上述的许多不同变体(在行尾使用不同数量的\r\n),但没有成功;到目前为止,我总是收到Internal Server Error

以上两行是否足以发送HTTP 303 响应?应该还有别的吗?

【问题讨论】:

  • 谢谢约翰!是的,我有,但这并不能解决我的问题。我得到的不是Internal Server Error,而是一个包含文本Location: http://192.168.1.109 的页面,而不是被重定向到该页面。
  • 所以我查看了 apache 错误日志,发现第一行是 Status: 303 See other\n 时没有错误。所以这个另一个问题在这部分是正确的。但是,第二行 (Location: ...) 似乎不起作用...

标签: python python-2.7 cgi http-status-codes http-status-code-303


【解决方案1】:

假设你正在使用 cgi (2.7)(3.5)

以下示例应重定向到同一页面。该示例不会尝试解析标头,检查发送了什么 POST,它只是在检测到 POST 时重定向到页面'/'

# python 3 import below:
# from http.server import HTTPServer, BaseHTTPRequestHandler
# python 2 import below:
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
import cgi
#stuff ...
class WebServerHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        try:
            if self.path.endswith("/"):
                self.send_response(200)
                self.send_header('Content-type', 'text/html')
                self.end_headers()

                page ='''<html>
                         <body>
                         <form action="/" method="POST">
                         <input type="submit" value="Reload" >
                         </form>
                         </body>
                         </html'''

                self.wfile.write(page)
        except IOError:
            self.send_error(404, "File Not Found {}".format(self.path))
    def do_POST(self):
        self.send_response(303)
        self.send_header('Content-type', 'text/html')
        self.send_header('Location', '/') #This will navigate to the original page
        self.end_headers()

def main():
    try:
        port = 8080
        server = HTTPServer(('', port), WebServerHandler)
        print("Web server is running on port {}".format(port))
        server.serve_forever()

    except KeyboardInterrupt:
        print("^C entered, stopping web server...")
        server.socket.close()


if __name__ == '__main__':
    main()

【讨论】:

  • 谢谢米哈尔!我得到一个错误虽然:(name 'self' is not defined。我正在使用python2。
  • @panos ,这是一个更加自我(哈哈)包含的示例,说明您要完成的工作。
  • @panos 现在应该兼容python 2
  • 谢谢你!我正在努力让它工作,但我在第一个 if 时得到了 IndentationError:...而且由于我是 python 新手,我真的不知道在哪里放置缩进...
  • @panos 立即尝试。
【解决方案2】:

通常浏览器喜欢在 HTTP 响应的末尾看到 /r/n/r/n

【讨论】:

    【解决方案3】:

    要非常小心 Python 自动执行的操作。 例如,在 Python 3 中, print 函数为每个打印添加了行尾,这可能会与 HTTP 在每条消息之间非常具体的行尾数混淆。 出于某种原因,您还需要一个内容类型标头。

    这在 Apache 2 上的 Python 3 中对我有用:

    print('Status: 303 See Other')
    print('Location: /foo')
    print('Content-type:text/plain')
    print()
    

    【讨论】:

      猜你喜欢
      • 2023-03-18
      • 1970-01-01
      • 2013-01-25
      • 1970-01-01
      • 2020-06-24
      • 2011-11-01
      • 1970-01-01
      • 2014-05-03
      • 2022-11-11
      相关资源
      最近更新 更多