I am trying to fetch image from my django server from my react app. Tried multiple configuration but nothing to rescue. It would be great if anyone could provide any insight or leads or something I am missing
React
Using react behind nginx (on client machine) so origin is always http://127.0.0.1
instead of http://localhost:3000
import axios from "axios"
export async function getImageFromNginx() {
const IMAGE_URL = "http://{SERVER_URL}/media/pages/64d3d8cb4d3bd545823595e4.png"
const config = {
mode: 'cors', // no-cors, *cors, same-origin
headers: {
'Access-Control-Allow-Origin' : 'http://127.0.0.1',
'Access-Control-Allow-Credentials': 'true',
},
auth: {'username': 'username', 'password':'password'},
withCredentials: true,
}
console.log(config)
try{
const response = await axios.get(IMAGE_URL, config).then((res)=>console.log("in axios",res))
console.log('Call to Nginx')
return await response.json();
}catch(error) {
return [];
}
}
Django
in django settings for cors, have installed django-cors-headers
and added app and middleware settings
CORS_ALLOWED_ORIGINS = ['http://127.0.0.1']
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_HEADERS = ['Content-Type', 'Access-Control-Allow-Origin']
CORS_ALLOW_METHODS = ['GET', 'POST', 'OPTIONS']
Django Method to serve file using nginx (on server)
def send_file(roots, file_name, disposition_type=None,
default_file_name=None):
valid = ['/download/{}'.format(root) for root in roots \
if os.path.exists(get_absolute_filename(root,file_name))]
if valid:
response = HttpResponse()
response['Content-Type'] = ''
if disposition_type is not None:
end_user_filename = default_file_name and default_file_name or file_name
response['Content-Disposition'] = "{}; filename={}".format(
disposition_type, end_user_filename)
response['X-Accel-Redirect'] = os.path.join(valid[0], file_name)
response['Access-Control-Allow-Origin'] = 'http://127.0.0.1/'
response['Access-Control-Allow-Methods'] = 'GET'
response['Access-Control-Allow-Headers'] = 'Content-Type, Access-Control-Allow-Origin'
response['Access-Control-Allow-Credentials'] = 'true'
else:
response = HttpResponseNotFound("Requested file is not available")
return response
Nginx configuration on server
CORS Related snippets
location /download/
{
alias /media/;
internal;
add_header 'Access-Control-Allow-Origin' 'http://127.0.0.1/' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Access-Control-Allow-Origin' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
add_header 'Access-Control-Allow-Credentials' 'true';
}
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'http://127.0.0.1/';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Access-Control-Allow-Origin';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
add_header 'Access-Control-Allow-Credentials' 'true';
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' 'http://127.0.0.1/' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Access-Control-Allow-Origin' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
add_header 'Access-Control-Allow-Credentials' 'true';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' 'http://127.0.0.1/' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Access-Control-Allow-Origin' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
add_header 'Access-Control-Allow-Credentials' 'true';
}
}
}
It's a common problem when you try to use django and react on the different domains.
You don't need to play with CORS here.
The best practice is to resolve it by nginx.
server {
listen 80;
server_name yourdomain.com;
# Serve React static files
location / {
# Point this to the directory where your React build outputs its static files.
root /path/to/react/build;
try_files $uri /index.html;
}
# Proxy requests to Django backend
location /backend/ {
# Point this to the IP and port where your Django app is running.
# If Django runs on the same server, you can use localhost or 127.0.0.1.
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Handle WebSockets
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
So, both apps will work on the same url, and won't have ny problems with cors.