XML-RPC Javascript Unsupported method ('OPTIONS')
We've got an XML-RPC server (implemented in python), and I'm trying to write a simple javascript app to send calls to it. Whatever library I make I seem to always get the error:
Unsupported method ('OPTIONS')
It's fair to开发者_如何学Go say I don't understand the underlying protocols for XML-RPC and HTTP as well as I should. But what I do know is that this works in python:
client = xmlrpclib.ServerProxy('http://localhost:2002')
client.T.run_process()
But the following javascript doesn't:
var client = new xmlrpc_client("", "localhost", 2002, "http")
var msg = new xmlrpcmsg("T.run_process()", {})
lert(client.send(msg));
I'm using this javascript library. But it seems I get the same error no matter what library I use, so I guess our server isn't conforming to some protocol that python doesn't mind about, is this right?
Using the standard SimpleXMLRPCServer from python, adding the following to the RequestHandler methods seemed to work for me:
class RequestHandler(SimpleXMLRPCRequestHandler):
rpc_paths = ('/RPC2',)
def do_OPTIONS(self):
self.send_response(200)
self.end_headers()
# Add these headers to all responses
def end_headers(self):
self.send_header("Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept")
self.send_header("Access-Control-Allow-Origin", "*")
SimpleXMLRPCRequestHandler.end_headers(self)
This may be CORS in action.
Julian is probably right. See this answer for details and some more links.
I was fighting against something similar recently.
The problem is that python's XMLRPC server does not include CORS headers (nor respond HTTP OPTIONS request) in the XML-RPC request.
I'm using Twisted to serve the XMLRPC Resource, and solved that adding the OPTIONS response and the headers to the XMLRPC request.
My code looks something like:
from twisted.web.xmlrpc import withRequest
class MyResourceEndpoint(xmlrpc.XMLRPC):
def render_OPTIONS(self, request):
request.setHeader('Access-Control-Allow-Origin', '*')
request.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')
request.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept')
return ""
@withRequest
def xmlrpc_my_method(self, request, my_params):
request.setHeader('Access-Control-Allow-Origin', '*')
request.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')
request.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept')
return "Whatever your method do"
root = resource.Resource()
root.putChild('', MyResourceEndpoint())
reactor.listenTCP(9090, server.Site(root))
reactor.run()
精彩评论