启用CORS的正确位置在哪里? [英] Where is the correct place to enable CORS?

查看:122
本文介绍了启用CORS的正确位置在哪里?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



当我去地址 http:// localhost:8000 / say_hello?name = Dave& times = 3 我得到以下输出:



[你好,戴夫,你好,戴夫,你好,戴夫]



这就是为什么我认为与服务器无关(它按预期工作)。



我使用以下代码从此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({
类型:'获取',
url:request_url,
dataType:jsonp,
crossDomain:true,
成功:function(data){
alert(data);
},
error:function()
{
alert(fail);
},

});
< / script>
< / body>
< / html>

然后我收到失败弹出窗口。



当我搜索网络时,我所能找到的是在服务器端进行的设置,如下所示:

 在服务器中添加以下标题:

标题集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({
类型:'获取',
url:request_url,
dataType:html,
crossDomain:true,
成功:函数(数据){
alert(数据);
},
错误:function()
{
alert (失败);
},

});
< / script>
< / body>
< / html>

Python:

 #!/ usr / bin / env python 
#encoding:utf8

'''
这是一个简单的HelloWorld示例展示使用Spyne编写Http api
的基础知识。这是一个示例:

$ curl http:// localhost:8000 / say_hello?name = Dave \& times = 3
[Hello,Dave,Hello,Dave ,Hello,Dave]
'''


导入日志记录

来自spyne.application import应用程序
来自spyne.decorator从spyne.protocol.json导入srpc
从spyne.protocol.http导入JsonDocument
从spyne.service导入HttpRpc
导入ServiceBase
来自spyne.model.complex import Iterable $ b来自spyne.model.primitive的$ b来自spyne.model.primitive的unsignedInteger
来自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)


类HelloWorldService(CorsService):

@srpc(String,UnsignedInteger,_returns = Iterable(String))
def say_hello(name ,次):

for i in range(times):
#yield'%s(Hello,%s)'%(callback,name)
yield { name:'Hello(%d):%s'%(i,name),address:%d +%d%(i,i)}


如果__name __ =='__ main__':
来自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(li stening to http://127.0.0.1:8000)
logging.info(wsdl at at:http:// localhost:8000 /?wsdl)

server.serve_forever( )


解决方案

您需要将此添加为您的第一行服务实施:

  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)

所以我您现在可以使用 CorsService 作为服务的父类来自动获取CORS标头,而不是使用 ServiceBase 。 / p>

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


I'm using Spyne (the example "hello world" code) to make a webservice that produces some json data and then I'm trying to consume this data in javascript code in client's browser.

When I go to the address http://localhost:8000/say_hello?name=Dave&times=3 I get the following output:

["Hello, Dave", "Hello, Dave", "Hello, Dave"]

That's why I think there is nothing to do with the server (it works as expected).

I use the following code to get the data from this webservice:

<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>

Then I get the "fail" popup.

As I searched the net, all I could find was a setting to be made on the server side as follows:

Add following header in the server: 

  Header set Access-Control-Allow-Origin *

  1. If any header setting must be changed on server side, how can I do that?
  2. If there is no need to change any server side settings, what should be the correct client side code?

EDIT

Here is the last version of both python and javascript code:

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()

解决方案

You need add this as the first line of your service implementation:

ctx.transport.resp_headers['Access-Control-Allow-Origin'] = '*'

However, that can get very annoying very fast, so here's a way to properly implement it:

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)

So instead of using ServiceBase, you can now use CorsService as parent class to your services to get the CORS header automatically.

Also note that it's more secure to set the header value only to the domain that hosts the Spyne service instead of using a wildcard.

这篇关于启用CORS的正确位置在哪里?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆