2012-09-19 45 views
39

我使用SimpleHTTPServer來測試我正在處理的一些網頁。它效果很好,但是我需要做一些跨域請求。這需要設置一個Access-Control-Allow-Origin標題以允許頁面被允許訪問的域。我可以使用python的SimpleHTTPServer設置標題嗎?

有沒有簡單的方法來設置一個標頭與SimpleHTTPServer並提供原始內容?每個請求的標題都是相同的。

回答

42

這是一個黑客位的,因爲它改變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) 
+0

如果您正在重新定義do_GET,請不要忘記發送頭文件:'def do_GET(self): self.send_head()' – user474708

+1

如果使用默認的do_GET(),則此解決方案不起作用。它不會調用end_headers。 – Koffiman

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

我想我應該更清楚一點,我仍然想要提供原始內容,但帶有附加標題,而不僅僅是標題。 – nynexman4464

9

我會說有這樣做,在這裏簡單的方法「只是加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處理程序,調用super -class 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 
... 
+0

嗯,是的,我正在尋找一兩行解決方案。 雖然 – nynexman4464

+0

複製該方法是下一個最佳解決方案,但它不應該向公衆提供self.send_header()和self.end_headers()API,因爲它只是混淆了消費開發人員。標題確實被添加到響應主體。 – yorkw

0

雖然這是一箇舊的答案,它在谷歌的第一個結果......

基本上什麼@ iMon0 suggested..Seems正確的實例嗎?.. 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生成的頁面/文件相同。

+1

我想原來的問題可能會更清楚,但我想要的是一種簡單的方式來提供用於開發目的的目錄中的內容,並添加一個頭以允許跨源請求。 我的理想應該是'python -m SimpleHTTPServer --header = Access-Control-Allow-Origin'。這是不可能的,所以你最終不得不實施一些代碼來做到這一點。 你當然可以擴展'SimpleHTTPServer'來做很多其他的事情。 – nynexman4464

+0

您應該可以從提供的內容中發佈標題?否則PHP現在提供它自己的網絡服務器,所以你不需要安裝Apache。允許你用一個目錄啓動它,僅此而已。只要你找到解決方案 – Mayhem

相關問題