2011-08-10 106 views
9

得到一個在localhost:8000上運行的django dev服務器和在localhost:3000上運行的nodejs服務器。我想導入JSON到服務器的NodeJS,但我得到這個錯誤:django tastypie和跨域json

XMLHttpRequest cannot load http://127.0.0.1:8000/api/presentation/?format=json . Origin http://localhost:3000 is not allowed by 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: '...' 
    }); 
}); 

我在想什麼/做錯了什麼?

回答

10

數據提供商需要設置跨域請求的策略(不是客戶端,爲您expressjs片段暗示)。

Someone發佈了主旨用一個簡單的Django中間件以注入所需的頭護理:

Middlware to allow's your django server to respond appropriately to cross domain XHR (postMessage html5 API).

+0

工作!非常感謝:D –

+2

我使用的是要點,但不適合我。試圖通過一個簡單的jquery在回溯中加載一個由django/python後端公開的簡單json。我也使用$ .getJSON方法。並且還在我的中間件設置中添加了提到的中間件。什麼可能是錯的?中間件必須添加的任何特定順序?還是我需要在每個響應中明確設置標題?(看起來好像看中間件的代碼)。或者我需要修改它以使用json mimetype?提前致謝。 – sbidwai

+0

我認爲在響應和請求中設置標頭是必需的。這是更新要點https://gist.github.com/1369619 –

1

你可以有也用JSONP

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

太棒了!但是,我如何定製回調名稱? – user507410

+0

在URL中包含'callback'參數。通過'http://127.0.0.1:8000/API /演示文稿格式= JSONP&回調= foo'。 – Jimothy

6

https://gist.github.com/426829 - 這個片段非常有用,但是使用骨幹到django服務器進行POST,我必須匹配訪問控制請求頭部頭部請求訪問控制允許頭部對響應。

咖啡:

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

蟒蛇: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   

希望這是很有用的!

+0

這個答案需要更多的選票。 –

0

在ajax POST代碼中爲我設置dataType:'text'而不是'jsonp'。

1

This gist是一個TastyPie資源基類。子類化的任何資源都將是跨域可訪問的。

它與其他人相似,但會將CORS標頭添加到全部對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) 
+0

這對我有效。只需在類頭中將Resource更改爲ModelResource即可。 – PhoebeB