Home > Software engineering >  Why CORS error come out when I call an API?
Why CORS error come out when I call an API?

Time:05-18

I deployed a project which has two APIs, login and loadMenu respectively, to a server. When I call the login API, everything is fine and I get the result.

But when I try to call the loadMenu API, a CORS problem comes out.

and here is my nginx configuration file:

server {
  listen 80;
  # set proper server name after domain set
  server_name xxxxxx;

  # Add Headers for odoo proxy mode
  proxy_set_header X-Forwarded-Host $host;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;
  proxy_set_header X-Real-IP $remote_addr;
  add_header X-Frame-Options "SAMEORIGIN";
  add_header X-XSS-Protection "1; mode=block";
  proxy_set_header X-Client-IP $remote_addr;
  proxy_set_header HTTP_X_FORWARDED_HOST $remote_addr;

  #   odoo    log files
  access_log  /var/log/nginx/odoo15-access.log;
  error_log       /var/log/nginx/odoo15-error.log;

  #   increase    proxy   buffer  size
  proxy_buffers   16  64k;
  proxy_buffer_size   128k;

  proxy_read_timeout 900s;
  proxy_connect_timeout 900s;
  proxy_send_timeout 900s;

  #   force   timeouts    if  the backend dies
  proxy_next_upstream error   timeout invalid_header  http_500    http_502
  http_503;

  types {
    text/less less;
    text/scss scss;
  }

  #   enable  data    compression
  gzip    on;
  gzip_min_length 1100;
  gzip_buffers    4   32k;
  gzip_types  text/css text/less text/plain text/xml application/xml application/json 
  application/javascript application/pdf image/jpeg image/png;
  gzip_vary   on;
  client_header_buffer_size 4k;
  large_client_header_buffers 4 64k;
  client_max_body_size 0;

    add_header 'Access-Control-Allow-Origin' "$http_origin" always;
    add_header 'Access-Control-Allow-Credentials' 'true' always;
  location / {
    #add_header 'Access-Control-Allow-Origin' "$http_origin" always;
    #add_header 'Access-Control-Allow-Credentials' 'true' always;
    if ($request_method = OPTIONS) {
        add_header 'Access-Control-Allow-Origin' "$http_origin"; # DO NOT remove THIS LINES (doubled with outside 'if' above)
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Max-Age' 1728000; # cache preflight value for 20 days
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'My-First-Header,My-Second-Header,Authorization,Content-Type,Accept,Origin';
        add_header 'Content-Length' 0;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
       return 204;
    }
    if ($request_method = POST) {
        add_header 'Access-Control-Allow-Origin' "$http_origin";
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' *;
    }
    #proxy_set_header host $http_host;    
    proxy_pass    http://127.0.0.1:8069;
    # by default, do not forward anything
    proxy_redirect off;
    proxy_cookie_path / "/; secure; HttpOnly;SameSite=None";
  }


  location /longpolling {
  proxy_pass http://127.0.0.1:8072;
  }
  location ~* .(js|css|png|jpg|jpeg|gif|ico)$ {
  expires 2d;
  proxy_pass http://127.0.0.1:8069;
  add_header Cache-Control "public, no-transform";
  }
  # cache some static data in memory for 60mins.
  location ~ /[a-zA-Z0-9_-]*/static/ {
  proxy_cache_valid 200 302 60m;
  proxy_cache_valid 404      1m;
  proxy_buffering    on;
  expires 864000;
  proxy_pass    http://127.0.0.1:8069;
  }
}

and here is the error message

Access to fetch at 'http://127.0.0.1:8069/web/login?redirect=http://127.0.0.1:8069/web/webclient/load_menus/1652856182783' (redirected from 'http://IP/web/webclient/load_menus/1652856182783') from origin 'http://localhost:8069' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

CodePudding user response:

Taking a stab-in-the-dark here but I'm guessing your API at 127.0.0.1:8069 (on the server) is responding with a fully-qualified redirect URL, eg

< HTTP/1.1 302 Found
< Location: http://127.0.0.1:8069/web/login?...

This obviously isn't a URL accessible to anything outside the server's internal network.

What you're missing is a proxy_redirect configuration to rewrite the Location response headers to use the external address...

proxy_redirect default;

# or the more verbose equivalent
# proxy_redirect http://127.0.0.1:8069 /;

As mentioned on your last attempt at this question, it's usually a sign of something wrong with your API design if it responds with 301 / 302 redirect.

  • Related