Got a django dev server running on localhost:8000 and a nodejs server on localhost:3000. I want to import json into the nodejs server but I'm getting this error:
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
This is my first foray into cross-domain fun so I'm WAY out of my depth.
I've added this to my routes in node (expressjs).
app.all('/', function(req, res){
re开发者_如何学Pythons.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.render('index', {
title: '...'
});
});
What am I missing / doing wrong?
The data provider needs to set a policy for cross domain request (not the client, as your expressjs snippets suggests).
Someone posted a gist with a simple Django middleware taking care of injecting the needed headers:
Middlware to allow's your django server to respond appropriately to cross domain XHR (postMessage html5 API).
- https://gist.github.com/426829
https://gist.github.com/426829 - This snippet was really useful however doing POST using backbone to django server i had to match Access-Control-Request-Headers header on request with Access-Control-Allow-Headers on response.
coffee:
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 with one extra line
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
Hope this is useful!
You could have also used JSONP like
http://127.0.0.1:8000/api/presentation/?format=jsonp
This gist is a TastyPie resource base class. Any resource subclassing this will be cross-domain accessable.
It's similar to others out there but will add CORS headers to all respones a TastyPie resource may give. This includes error responses and ImmediateHttpResponse exceptions
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)
There is a friendly and configurable Django module for this: django-cors-headers
Setting dataType: 'text' instead of 'jsonp' in the ajax POST code worked for me.
精彩评论