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
tryingtolearn
  • 2,528
  • 7
  • 26
  • 45
  • 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? – Igor Raush Oct 27 '15 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. – tryingtolearn Oct 27 '15 at 18:44
  • @IgorRaush "Remote Address:127.0.0.1:8000 Request URL:http://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." – tryingtolearn Oct 27 '15 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? – Igor Raush Oct 27 '15 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`... – Igor Raush Oct 27 '15 at 19:12
  • I did and I got: HTTP/1.0 301 MOVED PERMANENTLY Date: Tue, 27 Oct 2015 19:12:48 GMT Server: WSGIServer/0.2 CPython/3.4.1 Location: http://127.0.0.1:8000/xyz/api/abc/ Content-Type: text/html; charset=utf-8 X-Frame-Options: SAMEORIGIN – tryingtolearn Oct 27 '15 at 19:13
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/93532/discussion-between-tryingtolearn-and-igor-raush). – tryingtolearn Oct 27 '15 at 19:14

2 Answers2

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(...);
Igor Raush
  • 15,080
  • 1
  • 34
  • 55
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)

Ramesh Ponnusamy
  • 1,553
  • 11
  • 22