我可以使用python的SimpleHTTPServer设置标头吗?

时间:2012-09-19 16:42:39

标签: python cross-domain simplehttpserver

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

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

4 个答案:

答案 0 :(得分:48)

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

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

它不是1-2行,但不到20行;主要是样板。

#!/usr/bin/env python
import SimpleHTTPServer

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

        SimpleHTTPServer.SimpleHTTPRequestHandler.end_headers(self)

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


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

答案 1 :(得分:9)

我说没有简单的方法可以做到这一点,简单的意思是“只需添加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
...

答案 2 :(得分: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()

答案 3 :(得分: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:您回发所需的数据,无论您想要什么或如何,

以上示例对我来说工作正常,可以进一步扩展,它只是一个裸骨JSON后服务器。所以我会把这个放在SOF上,如果有人需要它,或者我自己会在几个月内回来。

这确实产生了一个有效的JSON文件,只有sTest对象,与PHP生成的页面/文件相同。