我可以用 python 的 SimpleHTTPServer 设置一个标题吗?

Posted

技术标签:

【中文标题】我可以用 python 的 SimpleHTTPServer 设置一个标题吗?【英文标题】:Can I set a header with python's SimpleHTTPServer? 【发布时间】:2012-09-12 00:36:20 【问题描述】:

我正在使用SimpleHTTPServer 来测试我正在处理的一些网页。它工作得很好,但是我需要做一些跨域请求。这需要设置一个Access-Control-Allow-Origin 标头以及允许该页面访问的域。

是否有一种简单的方法可以使用 SimpleHTTPServer 设置标头并提供原始内容?每个请求的标头都相同。

【问题讨论】:

【参考方案1】:

这有点小技巧,因为它改变了end_headers() 的行为,但我认为这比复制和粘贴整个SimpleHTTPServer.py 文件要好一些。

我的方法在子类中覆盖end_headers(),并在其中调用send_my_headers(),然后调用超类的end_headers()

也不是 1 到 2 行,但少于 20 行;主要是样板文件。

#!/usr/bin/env python
try:
    from http import server # Python 3
except ImportError:
    import SimpleHTTPServer as server # Python 2

class MyHTTPRequestHandler(server.SimpleHTTPRequestHandler):
    def end_headers(self):
        self.send_my_headers()

        server.SimpleHTTPRequestHandler.end_headers(self)

    def send_my_headers(self):
        self.send_header("Access-Control-Allow-Origin", "*")


if __name__ == '__main__':
    server.test(HandlerClass=MyHTTPRequestHandler)

【讨论】:

如果你要重新定义do_GET,也不要忘记发送标头:def do_GET(self): self.send_head() 如果使用默认的 do_GET(),此解决方案将不起作用。它不调用 end_headers。【参考方案2】:

我想说没有简单的方法,简单的意思是“只需添加 1-2 行来编写额外的标题并保留现有功能”。因此,最好的解决方案是继承 SimpleHTTPRequestHandler 类并重新实现功能,并添加新的标头。

通过查看 Python 库中 SimpleHTTPRequestHandler 类的实现,可以观察到为什么没有简单的方法可以做到这一点背后的问题:http://hg.python.org/cpython/file/19c74cadea95/Lib/http/server.py#l654

注意send_head() 方法,特别是方法末尾发送响应头的行。注意end_headers() 方法的调用。此方法将标头写入输出,并带有一个空行,表示所有标头的结束和响应正文的开始:http://docs.python.org/py3k/library/http.server.html#http.server.BaseHTTPRequestHandler.end_headers

因此,不可能子类化 SimpleHTTPRequestHandler 处理程序,调用超类 do_GET() 方法,然后只需添加另一个标头——因为当调用超类do_GET() 方法返回。它必须像这样工作,因为do_GET() 方法必须发送正文(请求的文件),并发送正文 - 它必须完成发送标头。

所以,再一次,我认为你坚持对 SimpleHTTPRequestHandler 类进行子类化,完全按照库中的代码实现它(只是复制粘贴它?),并在调用之前添加另一个标题end_headers() 中的send_head() 方法:

...
self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
# this below is the new header
self.send_header('Access-Control-Allow-Origin', '*')
self.end_headers()
return f
...

【讨论】:

嗯,是的,我正在寻找一两条线解决方案。复制该方法是下一个最佳解决方案 那么它不应该向公众提供 self.send_header() 和 self.end_headers() API,因为它所做的只是迷惑消费者开发者。标头确实已添加到响应正文中。【参考方案3】:
# coding: utf-8
import SimpleHTTPServer
import SocketServer
PORT = 9999

def do_GET(self):
    self.send_response(200)
    self.send_header('Access-Control-Allow-Origin', 'http://example.com')           
    self.end_headers()

Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
Handler.do_GET = do_GET
httpd = SocketServer.TCPServer(("", PORT), Handler)
httpd.serve_forever()

【讨论】:

我想我应该更清楚一点,我仍然想提供原始内容,但需要额外的标题,而不仅仅是标题。【参考方案4】:

虽然这是一个较旧的答案,但它是谷歌的第一个结果......

基本上@iMon0 的建议..似乎正确?..doPOST 的示例

def do_POST(self):
    self.send_response()
    self.send_header('Content-type','application/json')
    self.send_header('Access-Control-Allow-Origin','*')
    self.end_headers()
    sTest = 
    sTest['dummyitem'] = "Just an example of JSON"
    self.wfile.write(json.dumps(sTest))

通过这样做,流程感觉正确..

1:你收到一个请求

2:您应用所需的标头和响应类型

3:你发回你想要的数据,无论你想要什么或如何。,

上面的例子对我来说很好,可以进一步扩展,它只是一个简单的 JSON 发布服务器。所以我会把它留在 SOF 上,以防有人需要它,或者我自己会在几个月后回来。

这确实会生成一个有效的 JSON 文件,其中只有 sTest 对象,与 php 生成的页面/文件相同。

【讨论】:

我想最初的问题可能更清楚,但我想要的是一种简单的方法来提供目录中的内容以用于开发目的,并添加一个标题以允许跨源请求。我的理想是python -m SimpleHTTPServer --header=Access-Control-Allow-Origin。这是不可能的,所以你最终不得不实现一些代码来做到这一点。您当然可以扩展SimpleHTTPServer 来做许多其他事情。 您应该能够从所提供的内容中发布标题吗?否则 PHP 现在提供它自己的网络服务器,所以你不需要安装 apache。允许您使用目录启动它,仅此而已。只要你找到解决办法 self.send_response 会导致错误。 1)它是一个函数,所以它实际上是 self.send_response() 和 2)该函数总是要求您为 code 参数传递一个值。 self.send_response = 错字。

以上是关于我可以用 python 的 SimpleHTTPServer 设置一个标题吗?的主要内容,如果未能解决你的问题,请参考以下文章

爬取4k图片

爬取4k图片

在ROS的同一文件夹中编译多个包

python3 找不到我可以用 python2 导入的模块

我可以用python创建一个产品吗?

我可以用 Python 在 Xcode 中开发 Qt GUI 吗?