58

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

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

4

4 回答 4

56

这有点像 hack,因为它会改变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)
于 2012-11-13T01:42:37.027 回答
10

我想说没有简单的方法可以做到,简单的意思是“只需添加 1-2 行来编写附加标题并保留现有功能”。因此,最好的解决方案是对类进行子SimpleHTTPRequestHandler类化并重新实现功能,并添加新的标头。

SimpleHTTPRequestHandler通过查看Python 库中的类的实现,可以观察到为什么没有简单的方法背后的问题: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
...
于 2012-09-19T17:15:00.643 回答
4
# 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()
于 2012-09-19T16:52:24.950 回答
0

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

基本上@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:你发回你想要的数据,无论你想要什么或如何。,

The above example is working fine for me and can be extended further, its just a bare bone JSON post server. So i'll leave this here on SOF incase someone needs it or i myself come back in a few months for it.

This does produce a valid JSON file with only the sTest object, Same as a PHP generated page/file.

于 2015-09-15T06:14:38.373 回答