【问题标题】:django tastypie and cross domain jsondjango sweetpie 和跨域 json
【发布时间】:2011-10-24 06:30:58
【问题描述】:

在 localhost:8000 上运行 django 开发服务器,在 localhost:3000 上运行 nodejs 服务器。我想将 json 导入 nodejs 服务器,但出现此错误:

XMLHttpRequest 无法加载 http://127.0.0.1:8000/api/presentation/?format=json。起源 http://localhost:3000 不被 Access-Control-Allow-Origin 所允许

这是我第一次涉足跨领域的乐趣,所以我的深度不够。

我已将此添加到节点 (expressjs) 中的路由中。

app.all('/', function(req, res){
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  res.render('index', {
    title: '...'
  });
});

我错过了什么/做错了什么?

【问题讨论】:

    标签: django json node.js express


    【解决方案1】:

    为此有一个友好且可配置的 Django 模块:django-cors-headers

    【讨论】:

      【解决方案2】:

      This gist 是一个 TastyPie 资源基类。任何对其进行子类化的资源都可以跨域访问。

      它与其他类似,但会将 CORS 标头添加到 all 响应 TastyPie 资源可能给出的响应。这包括错误响应和 ImmediateHttpResponse 异常

      from tastypie.resources import Resource
      from tastypie.exceptions import ImmediateHttpResponse
      from django.http import HttpResponse
      
      
      class CorsResource(Resource):
      
          """ adds CORS headers for cross-domain requests """
      
          def patch_response(self, response):
      
              allowed_headers = ['Content-Type', 'Authorization']
      
              response['Access-Control-Allow-Origin'] = '*'
              response['Access-Control-Allow-Headers'] = ','.join(allowed_headers)
              return response
      
          def dispatch(self, *args, **kwargs):
              """ calls super and patches resonse headers
                  or
                  catches ImmediateHttpResponse, patches headers and re-raises
              """
      
              try:
                  response = super(CorsResource, self).dispatch(*args, **kwargs)
                  return self.patch_response(response)
              except ImmediateHttpResponse, e:
                  response = self.patch_response(e.response)
                  # re-raise - we could return a response but then anthing wrapping
                  # this and expecting an exception would be confused
                  raise ImmediateHttpResponse(response)
      
          def method_check(self, request, allowed=None):
              """ Handle OPTIONS requests """
              if request.method.upper() == 'OPTIONS':
      
                  if allowed is None:
                      allowed = []
      
                  allows = ','.join([s.upper() for s in allowed])
      
                  response = HttpResponse(allows)
                  response['Allow'] = allows
                  raise ImmediateHttpResponse(response=response)
      
              return super(CorsResource, self).method_check(request, allowed)
      

      【讨论】:

      • 这对我有用。只是在类头中将 Resource 更改为 ModelResource。
      【解决方案3】:

      在 ajax POST 代码中设置 dataType: 'text' 而不是 'jsonp' 对我有用。

      【讨论】:

        【解决方案4】:

        https://gist.github.com/426829 - 这个 sn-p 非常有用,但是使用主干对 django 服务器进行 POST 我必须根据请求将 Access-Control-Request-Headers 标头与 Access-Control 匹配-Allow-Headers 响应。

        咖啡:

        auth = (xhr) ->
        xhr['xhrFields']= {withCredentials: true}
        xhr.setRequestHeader('Access-Control-Allow-Credentials', 'true' )
        xhr.header('Access-Control-Allow-Origin', "*")
        xhr.header('Access-Control-Allow-Methods', 'GET,POST,PUT,HEAD,DELETE,OPTIONS')
        xhr.header('Access-Control-Allow-Headers', 'Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control')  
        

        python: https://gist.github.com/426829 多了一行

        def process_request(self, request):
        
            if 'HTTP_ACCESS_CONTROL_REQUEST_METHOD' in request.META:
                response = http.HttpResponse()
                response['Access-Control-Allow-Origin']  = XS_SHARING_ALLOWED_ORIGINS
                response['Access-Control-Allow-Methods'] = ",".join( XS_SHARING_ALLOWED_METHODS )
                response['Access-Control-Allow-Headers'] = "Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control"
                return response
        
            return None          
        

        希望这有用!

        【讨论】:

          【解决方案5】:

          你也可以使用JSONP like

          http://127.0.0.1:8000/api/presentation/?format=jsonp 
          

          【讨论】:

          • 太棒了!但是如何自定义回调名称呢?
          • 在 URL 中包含 callback 参数。 http://127.0.0.1:8000/api/presentation?format=jsonp&callback=foo.
          【解决方案6】:

          数据提供者需要为跨域请求设置策略(不是客户端,正如您的 expressjs sn-ps 建议的那样)。

          Someone 发布了一个要点,其中包含一个简单的 Django 中间件,负责注入所需的标头:

          中间件允许您的 django 服务器适当地响应跨域 XHR(postMessage html5 API)。

          【讨论】:

          • 我正在使用要点,但对我不起作用。尝试通过简单的 jquery 加载由 django/python 后端公开的简单 json。我也在使用 $.getJSON 方法。并且还在我的中间件设置中添加了提到的中间件。什么可能是错的?必须添加中间件的任何特定顺序?或者我是否也需要在每个响应中明确设置标题? (看起来不像看中间件的代码)。还是我需要修改它以使用 json mimetype?提前致谢。
          • 我认为需要在响应和请求中设置标头。这是更新的要点gist.github.com/1369619
          猜你喜欢
          • 1970-01-01
          • 2013-01-01
          • 2012-01-01
          • 2013-06-22
          • 1970-01-01
          • 1970-01-01
          • 2013-01-09
          • 2013-07-11
          • 2018-03-22
          相关资源
          最近更新 更多