1

我正在使用Spyne(示例“hello world”代码)创建一个生成一些json数据的 web 服务,然后我试图在客户端浏览器的 javascript 代码中使用这些数据。

当我转到该地址时,http://localhost:8000/say_hello?name=Dave&times=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&times=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 *
  1. 如果必须在服务器端更改任何标头设置,我该怎么做?
  2. 如果不需要更改任何服务器端设置,那么正确的客户端代码应该是什么?

编辑

这是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&times=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\&times=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()
4

2 回答 2

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,您现在可以使用CorsService作为服务的父类来自动获取 CORS 标头,而不是使用 。

另请注意,仅将标头值设置为托管 Spyne 服务的域而不是使用通配符更安全。

于 2014-07-02T11:29:03.593 回答
1

无需添加任何客户端代码。

您只需将以下内容添加到服务器发送的响应的标头中:

访问控制允许来源:*

有关各种服务器设置的更多信息,请参阅http://enable-cors.org/server.html。不熟悉 Spyne,但这可能会有所帮助

http://spyne.io/docs/2.10/manual/06_metadata.html#protocol-headers

于 2014-07-01T17:45:10.187 回答