5

I'm trying to upload an image from local by using base64 to do image detection.
And everything works fine in localhost and postman.
But after deploying, I got CROS error.

I've already got cors middleware in server.js

const express = require("express");    
const cors = require("cors");
const bodyParser = require("body-parser");

const app = express();

app.use(cors());

app.use(bodyParser.json({ limit: "10000kb", extended: true }));
app.use(bodyParser.urlencoded({ limit: "10000kb", extended: true }));

The cors middleware works fine when fetching image with url,
But when I tried to upload image from local by using base64, the console shows:

No 'Access-Control-Allow-Origin' header is present on the requested resource.

Here's the solution I've tried:

  1. cors-anywhere
App.js

    const proxyUrl = 'https://cors-anywhere.herokuapp.com/';
    
    fetch(proxyUrl + API_CALL.IMAGE_URL, {
          method: 'post',
          headers: {'Content-Type': 'application/json'},
          body: JSON.stringify({
            inputLink: inputLink,
            inputMethod: inputMethod
          }),
          credentials: 'include'
        })

It then shows 413 payload too large.

Since there's no error when testing in localhost and postman, I found out some articles said it might still be the cors error.

  1. CORS preflight

server.js

    const corsOptions = {
        origin: 'https://front-end-url/',
        methods: 'GET, POST, PUT',
        credentials: true,
        allowedHeaders: 'Content-Type,Authorization',
        exposedHeaders: 'Content-Range,X-Content- Range'
    };
    app.options('/imageUrl', cors(corsOptions));

It shows error:

CORS policy: Response to preflight request doesn't pass access control check: 
The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' 
when the request's credentials mode is 'include'
  1. After I remove credentials: 'include', it shows 413 payload too large again.

I'm so confused... Does anyone know how to fix it? Thank you.

João Pimentel Ferreira
  • 14,289
  • 10
  • 80
  • 109
user13145792
  • 241
  • 1
  • 2
  • 8
  • this doesn't happen on localhost at all? – PayamB. Mar 31 '20 at 09:32
  • @PayamBeirami It works fine on local host and postman, no error. – user13145792 Mar 31 '20 at 09:41
  • 2
    The 413 error is the actual problem. That’s what’s causing the browser to log the CORS message — not the other way around. You don’t have a CORS problem. You have 413 problem. If you fix the cause of the 413 problem, you’re likely gonna find that your existing CORS configuration is already working as expected. – sideshowbarker Mar 31 '20 at 09:46
  • 2
    First, you need to identify who is answering the 413 error. It could be your express server, or it could be something else. For example a nginx proxy that redirects requests to your express server. If this were the case, you should check if these have any setting like buffer sizes and such – Gerard Mar 31 '20 at 10:36
  • Hello @sideshowbarker , I changed the bodyParser limit to 100000000kb, and also changed the limit in json.js & text.js in node_modules > body-parser > lib folder, but it still shows 413 error. I'm deploying on heroku. Is the error not about bodyParser, but about heroku? – user13145792 Mar 31 '20 at 10:59
  • Hello @Gerard , I changed the bodyParser limit to 100000000kb, and also changed the limit in json.js & text.js in node_modules > body-parser > lib folder, but it still shows 413 error. I'm deploying on heroku. Is the error not about bodyParser, but about heroku? – user13145792 Mar 31 '20 at 10:59
  • About upload size, I’m not aware of any limits that Heroku imposes. – sideshowbarker Mar 31 '20 at 11:37
  • Thank you guys! I find out the answer. – user13145792 Mar 31 '20 at 13:46

3 Answers3

19

Finally fix the error by placing express.json() AFTER bodyParser.

like this:

app.use(bodyParser.json({limit: '50mb'}));
app.use(bodyParser.urlencoded({limit: '50mb', extended: true}));
app.use(express.json());

If runing express.json() first, express would set the global limit to 1mb.

For the next person that needs more detail: Error: request entity too large
And for the person who needs to set Nginx config file: Increasing client_max_body_size in Nginx conf on AWS Elastic Beanstalk

user13145792
  • 241
  • 1
  • 2
  • 8
  • 1
    Im sure my error is coming from here and I am on ELB too. My server throws a CORS error when my post request body content length is over 1 MB! Still cant fix it. – InfinitePrime Jun 24 '20 at 13:52
5

In express use

app.use(bodyParser.json({ limit: '50mb' }))
app.use(bodyParser.urlencoded({ limit: '50mb', extended: true, parameterLimit: 50000 }))

But then in Nginx you also have to edit /etc/nginx/nginx.conf and add the following line inside http block:

client_max_body_size 50M;

Then restart Nginx with sudo service nginx restart

João Pimentel Ferreira
  • 14,289
  • 10
  • 80
  • 109
0
This solution is for ANDROID 

In my case @Headers("Content-Type: application/json") is used extra which is not needed.

@Multipart

@POST("user-management/user/profile")
@Headers("Content-Type: application/json")
fun updateProfileImage( @Part file: MultipartBody.Part,@Header("Authorization") authKey: String): Call<ProfileImageResponse>

I have removed header @Headers("Content-Type: application/json") As multipart I am using so not to use above header.

After removal of that Header code executed successfully.

@Multipart
@POST("user-management/user/profile")
fun updateProfileImage( @Part file: MultipartBody.Part,@Header("Authorization") authKey: String):Call<ProfileImageResponse>
Bhavesh Chand
  • 495
  • 6
  • 7