3

SOLUTION: Add a trailing slash to the end of the url...

"http://127.0.0.1:8000/xyz/api/abc/" instead of "http://127.0.0.1:8000/xyz/api/abc"

....

I have successfully created a Django Rest API and am able to store and host data locally it seems. I have built an angularjs1.0 app separately and am attempting to extract the data via $http get request however I'm running into this error:

XMLHttpRequest cannot load http://127.0.0.1:8000/xyz/api/abc. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://172.20.9.163:8080' is therefore not allowed access.

I have attempted to install CORS and have added it to my INSTALLED_APPS, yet nothing seems to be working yet.

This is the get request:

getABC : function() {
            $http({
                method: 'GET',
                url: 'http://127.0.0.1:8000/xyz/api/abc',
                cache: false
            }).success(function(data) {
                console.log(data)
                callback(data);
            });
        },

Here's a look at my Django settings.py file:

INSTALLED_APPS = (
    'xyz',
    'corsheaders',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
)

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',

)

CORS_ORIGIN_ALLOW_ALL = True
7
  • Can you open the Network tab in Dev tools and check the response to your AJAX request? Does it actually contain the Access-Control-Allow-Origin header? Commented Oct 27, 2015 at 18:38
  • Sorry, where should I be seeing this? I've got the network tab open but I don't see an ajax request response anywhere. Commented Oct 27, 2015 at 18:44
  • @IgorRaush "Remote Address:127.0.0.1:8000 Request URL:127.0.0.1:8000/xyz/api/abc Request Method:GET Status Code:301 MOVED PERMANENTLY (from cache)" And when clicking the "response" tab it says "This request has no response data available." Commented Oct 27, 2015 at 18:46
  • Something is off. Your API is returning a redirect response. Is there a Location header on that response? Can you run curl --head http://localhost:8000/xyz/api/abc from the command line? Commented Oct 27, 2015 at 19:11
  • Also, it appears that the request may not even reach the server, it is cached in the browser as a 301 Moved Permanently... Commented Oct 27, 2015 at 19:12

2 Answers 2

11

TL;DR

Issue your AJAX request to a slash-appended URL.

Explanation

After our discussion, it appears that the culprit is Django's automatic APPEND_SLASH = True which is enabled when CommonMiddleware is enabled.

This causes the AJAX request from your Angular app to first hit a 301 Moved Permanently redirect to the slash-appended URL. However, the corsheaders middleware does not act on this response, so the browser complains about a missing Access-Control-Allow-Origin header.

This is solved by requesting the slash-appended URL directly, and bypassing the 301 redirect altogether.

$http({
    method: 'GET',
    url: 'http://127.0.0.1:8000/xyz/api/abc/',  // trailing slash here
    cache: false
}).success(...);
Sign up to request clarification or add additional context in comments.

Comments

0

Install django-crops-headers

pip install django-cors-headers

In setting.py:

MIDDLEWARE = [
             #...
                 'corsheaders.middleware.CorsMiddleware',
                 'django.middleware.common.CommonMiddleware',
             ]
INSTALLED_APPS = [

                'corsheaders',
                 #...
                ]

Set CORS_ORIGIN_ALLOW_ALL is True

CORS_ORIGIN_ALLOW_ALL = True  # this allows all domains

Or to allow specific domains 

CORS_ORIGIN_WHITELIST = (
'http://example.com',
'http://127.0.0.1:8000',
'http://localhost:8000',
 )

In Ajax call(front end) add headers:

 var get_request = $.ajax({
  type: 'GET',
  "headers": {
          "accept": "application/json",
          "Access-Control-Allow-Origin":"*"
      },
  url: 'http://example.com',
});

If it is not solved, You should enable the core in requesting server(http://example.com)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.