如何在JSON-RPC服务器上响应HTTP OPTIONS请求

4 投票
3 回答
11772 浏览
提问于 2025-04-15 21:15

我的 JSON-RPC 客户端(在浏览器中使用 dojo JSON-RPC)向我的 JSON-RPC 服务器发起了一个请求,地址是 myserver.com/12345(使用 Python 2.5 和 SimpleJSONRPCServer)。

服务器接收到一个 HTTP 请求,头部是 "OPTIONS / HTTP/1.1",但默认情况下它无法处理这个请求,所以我为这个请求写了一个自定义的处理程序。

浏览器发送的请求头内容是:

OPTIONS / HTTP/1.1
Host: myserver:12345
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.8) Gecko/20100214 Linux Mint/8 (Helena) Firefox/3.5.8 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.7,de;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Origin: http://myserver.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: x-requested-with

而我发送的响应看起来是这样的:

HTTP/1.0 200 OK
Server: BaseHTTP/0.3 Python/2.5
Date: Mon, 05 Apr 2010 18:58:34 GMT
Access-Control-Allow-Method: POST
Access-Control-Allow-Headers: POST
Allow: POST
Content-Type: application/json-rpc
Content-length: 0

但是在浏览器中,我遇到了以下错误:

错误:无法加载 http://myserver.com:12345 状态:0

我确认这个 JSON 服务是可以从网络上访问的。

现在的问题是,浏览器(比如 Firefox)期望响应的头部应该是什么样的?或者说,问题可能出在其他地方吗?

3 个回答

1

看看我的代码。它在Chrome浏览器中运行的客户端JavaScript代码是可以正常工作的。

class MyHandler(BaseHTTPRequestHandler):
    def do_OPTIONS(self):           
        self.send_response(200, "ok")       
        self.send_header('Access-Control-Allow-Origin', '*')                
        self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
        self.send_header("Access-Control-Allow-Headers", "X-Requested-With")        

    def do_GET(self):           
        self.send_response(200)
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Content-type',    'text/html')                                    
        self.end_headers()              
        self.wfile.write("<html><body>Hello world!</body></html>")
        self.connection.shutdown(1) 
3

加上代码试试看,对我来说运行得很好:

class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
...
...
    def do_OPTIONS(self):
        self.send_response(200, "ok")
        self.send_header('Access-Control-Allow-Origin', self.headers.dict['origin'])
        self.send_header('Access-Control-Allow-Methods', 'POST, OPTIONS')
2

可以查看一下CORS规范

顺便说一下,HTTP有一个头部注册表,您可以查看http://www.iana.org/assignments/message-headers/prov-headers.htmlhttp://www.iana.org/assignments/message-headers/perm-headers.html,这些链接会引导您找到正确的规范。

撰写回答