我正在使用Spyne(示例"hello world" code)制作一个产生一些json
数据的网络服务,然后我试图在客户端浏览器的javascript代码中使用这些数据。
当我转到地址http://localhost:8000/say_hello?name=Dave×=3
时,我得到以下输出:
["Hello, Dave", "Hello, Dave", "Hello, Dave"]
这就是为什么我认为与服务器无关(它按预期工作)。
我使用以下代码从此Web服务获取数据:
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script src="jquery-1.11.1.min.js" ></script>
<script>
var request_url = 'http://localhost:8000/say_hello?name=Dave×=3';
$.ajax( {
type:'Get',
url:request_url,
dataType: "jsonp",
crossDomain : true,
success:function(data) {
alert(data);
},
error: function()
{
alert("fail");
},
});
</script>
</body>
</html>
然后我得到“失败”弹出窗口。
当我搜索网络时,我所能找到的只是在服务器端进行的设置如下:
Add following header in the server:
Header set Access-Control-Allow-Origin *
这是python和javascript代码的最后一个版本:
HTML:
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script src="jquery-1.11.1.min.js" ></script>
<script>
var request_url = 'http://localhost:8000/say_hello?name=Dave×=3';
var jdata = 'none'
$.ajax( {
type:'Get',
url:request_url,
dataType: "html",
crossDomain : true,
success:function(data) {
alert(data);
},
error: function()
{
alert("fail");
},
});
</script>
</body>
</html>
的Python:
#!/usr/bin/env python
# encoding: utf8
'''
This is a simple HelloWorld example to show the basics of writing a Http api
using Spyne. Here's a sample:
$ curl http://localhost:8000/say_hello?name=Dave\×=3
["Hello, Dave", "Hello, Dave", "Hello, Dave"]
'''
import logging
from spyne.application import Application
from spyne.decorator import srpc
from spyne.protocol.json import JsonDocument
from spyne.protocol.http import HttpRpc
from spyne.service import ServiceBase
from spyne.model.complex import Iterable
from spyne.model.primitive import UnsignedInteger
from spyne.model.primitive import String
from spyne.server.wsgi import WsgiApplication
class CorsService(ServiceBase):
origin = '*'
def _on_method_return_object(ctx):
ctx.transport.resp_headers['Access-Control-Allow-Origin'] = \
ctx.descriptor.service_class.origin
CorsService.event_manager.add_listener('method_return_object',
_on_method_return_object)
class HelloWorldService(CorsService):
@srpc(String, UnsignedInteger, _returns=Iterable(String))
def say_hello(name, times):
for i in range(times):
#yield '%s("Hello, %s")' % (callback, name)
yield {"name": 'Hello (%d): %s' % (i, name), "address": "%d + %d" % (i, i)}
if __name__=='__main__':
from wsgiref.simple_server import make_server
logging.basicConfig(level=logging.DEBUG)
application = Application([HelloWorldService], 'spyne.examples.hello.http',
in_protocol=HttpRpc(validator='soft'),
out_protocol=JsonDocument(ignore_wrappers=True),
)
wsgi_application = WsgiApplication(application)
server = make_server('0.0.0.0', 8000, wsgi_application)
logging.info("listening to http://127.0.0.1:8000")
logging.info("wsdl is at: http://localhost:8000/?wsdl")
server.serve_forever()
答案 0 :(得分:4)
您需要将此添加为服务实施的第一行:
ctx.transport.resp_headers['Access-Control-Allow-Origin'] = '*'
然而,这可能会非常烦人,所以这是一种正确实现它的方法:
class CorsService(ServiceBase):
origin = '*'
def _on_method_return_object(ctx):
ctx.transport.resp_headers['Access-Control-Allow-Origin'] = \
ctx.descriptor.service_class.origin
CorsService.event_manager.add_listener('method_return_object',
_on_method_return_object)
因此,您现在可以使用ServiceBase
作为服务的父类来自动获取CORS标头,而不是使用CorsService
。
另请注意,将标头值仅设置为承载Spyne服务的域而不是使用通配符更安全。
答案 1 :(得分:1)
无需添加任何客户端代码。
您只需将以下内容添加到服务器发送的响应的标头中:
Access-Control-Allow-Origin:*
有关各种服务器设置的详细信息,请参阅http://enable-cors.org/server.html。不熟悉Spyne,但这可能会有所帮助
http://spyne.io/docs/2.10/manual/06_metadata.html#protocol-headers