1

Suppose I have two servers A and B:
A -> React App server
B -> API Server (in my case Node with Express)
Both of which I have control.

I have CORS enabled on server B, and on development am using proxy in my client app's package.json to query the API server.

Now the problem is when I send a GET request from server A to the API server and ask it to do a redirect to another external URL I get a CORS error in my React App.

But, when I make a GET request to the API server via Postman I am redirected. I understand that it happens because the react app server is not registered with CORS while the API server is.

And this issue can be mitigated if both the applications are on the same server. Correct me if I am wrong?

Am currently doing a workaround by making a GET request to the API server, getting the redirect URL as a response and doing a redirect on the client side.

Now my question is, whether there is any other possible way in which I don't have to get the redirect url as a response/ put both applications on same server and instead do a redirect straightaway?

I want the request flow to be:
React App [app.com] ----GET----> Api server[api.app.com]) ----REDIRECT----> External URL

My current implementation:

API Snippet

try {
    let url = await Urls.findOne({ shortCode: shortCode });

    if(!url) {
        // Send 404
        return res.status(404).send({ status: "NOT_FOUND" });
    }
    // Redirect to original URL
    //res.redirect(url.longUrl);
    return res.status(200).send({ status: "FOUND", url: url.longUrl });
}
catch(error) {
    console.log(error);
    return res.status(500).send({ status: "FAILED" });
}

Client Side

componentDidMount() {
    let id = this.props.match.params.id;

    axios.get(`/api/${id}`)
        .then(response => {
            window.location.replace(response.data.url);
        })
        .catch(error => {
            this.setState({ displayError: true, errorType: error.response.data.status })
        });
}
Ayan
  • 2,738
  • 3
  • 35
  • 76
  • It doesn't seem to be possible (see first answer [here](https://stackoverflow.com/questions/18539403/chrome-cancels-cors-xhr-upon-http-302-redirect)). Putting app and API on the same origin should work. – Johannes Reuter Nov 14 '18 at 07:42
  • ok. Any idea on how the url shorteners handle this scenario since my project is of a url shortener. – Ayan Nov 14 '18 at 07:53
  • If your app is served by nginx, you can proxy the api-traffic to the API server if you put it all under the path 'api'. Like [here](https://github.com/flash1293/ekofe/blob/master/client/nginx.conf#L26) – Johannes Reuter Nov 14 '18 at 07:56
  • Currently am proxying requests from `localhost:3000` to api server `localhost:3001` via proxy in package.json of the react app. Will serving the app by nginx be differently handled? See [here](https://github.com/whimsicaldreamer/shorten/blob/master/client/package.json#L25) – Ayan Nov 14 '18 at 08:01

2 Answers2

0

You can use res.redirect(301, 'http://example.com'); for redirect to external URL in express and in terms of CORS i think you should not get that error in react app because you are doing a server redirect and CORS errors occurs when you are trying to hit an server API from the front end URL and that has not been added to CORS or you can set you CORS headers in your server as * or set specific URL that you want to give access to. If you are getting CORS error in redirect from server API response then you are probably doing something not right.

  • I tried using 301, 302 but redirect is not happening. I have enabled CORS using the cors module. Redirect happens when I hit the server API with postman but not from react app – Ayan Nov 14 '18 at 08:22
  • @Ayan, can you please how did you solve this issue? I am in the same boat – mark Apr 07 '21 at 23:46
  • What's your application use case? – Ayan Apr 08 '21 at 16:30
  • @mark I kept my initial implementation. Requested the api server for the original url and then did a redirect on the client side. If I needed to do a straight redirect then I cant use a REST api server. – Ayan Apr 08 '21 at 17:08
  • Thanks, Ayan for your reply. I think your solution oaky as long as no sensitive information in the URL returned from api server – mark Apr 08 '21 at 17:18
0

Are you sure response.data.url is valid url or undefined? Try console.log(response.data.url) to confirm. If is undefined replace res.send() from server with res.json()

KibGzr
  • 2,053
  • 14
  • 15