Not using 'localhost' in HOST for development with create-react-app - reactjs

My problem is quite simple: I would like to avoid using localhost at the end of my HOST env variable with create-react-app. However it seems that if the URL doesn't end with .localhost, the script will try to resolve the URL against a DNS server.
I would like to avoid that and just use the same URL domain as my backend server is using, to avoid CORS problems (and I wish not to configure my backend to allow CORS because that's not how the production infrastructure is).
Thanks :)

If you want to use some custom domain locally, without resolving it agains a DNS server, you can add that domain to your hosts file.
Location of hosts file on Windows:
C:\Windows\System32\drivers\etc\hosts
Location of hosts file on Mac:
/etc/hosts
You can modify the hosts file by adding the following line to it:
127.0.0.1 yourcustomdomain.com
This will bind yourcustomdomain.com to your local IP. Now you can use yourcustomdomain.com in your create-react-app.

The true problem you're facing here is CORS. The standard solution for this is actually to just proxy your request, so that they're hitting from the same origin. Webpack has a clean way to do this. See this blog by facebook: https://facebook.github.io/create-react-app/docs/proxying-api-requests-in-development
This has gotten incredibly easy to do now. All you need to do is add a proxy field to your package.json. For example -
"proxy": "http://localhost:4000",

Related

Base URL Discrepancy Between Localhost and Deployed - create-react-app

I am building a web application from the ASP.Net Core React template, whose "ClientApp" React portion appears to be a 'create-react-app' project. When I deploy the app to IIS, it gets hosted in a subfolder from the root, i.e. http://myserver.com/SubApp. Because of this, I have changed the "homepage" value in package.json to http://myserver.com/SubApp.
What I am now experiencing is that when I am making fetch calls in my javascript code locally, if I use fetch('/myendpoint'), the the url requested locally is https://localhost:44315/myendpoint (which works), but when deployed, this url becomes http://myserver.com/myendpoint, which does not work.
Conversely, when I make the endpont fetch('myendpoint') (no leading slash), the server requests the correct URL http://myserver.com/SubApp/myendpoint but localhost fetches the incorrect URL, https://localhost:44315/SubApp/myendpoint.
I understand that the leading slash makes the request from the root, but the root appears to be different in localhost vs. on the server.
For local debugging purposes, I tried setting a proxy in package.json to https://localhost:44315 so that hopefully fetch('myendpoint') (no leading slash) would work in my local environment, but when I try this, chrome prompts me to sign in repeatedly without ever successfully making the request.
I feel like I am almost there, but I must be missing something. How can I configure my package.json (or other project configuration) to make the fetch commands succeed on both localhost and my server, without doing something hacky like checking the URL in the javascript code before every fetch?
What you need is Proxying API Requests in Development.
It easily allows you to call any endpoint in development and forward it to your backend or other location without CORS issues or your problem of mismatched endpoints.
You will have to use the manual configuration option, since the default proxy setup only helps with host/port forwarding.
Install http-proxy-middleware as a dev dependency:
$ npm -i http-proxy-middleware --save-dev
Following the guide linked above, you can use this configuration:
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/SubApp/*',
createProxyMiddleware({
target: 'localhost://44315', // or anything else, point to your dev backend
pathRewrite: {
'^/SubApp': '/', // remove base path
},
})
);
};
You can then fetch with the /SubApp part in the request which will be removed in developement. You can use other configurations to achieve this, this is one example.
I had this same experience as well and found that setting the homepage value in the package.json is a dead end. What you want to do is make use of the PUBLIC_URL environment variable to set a full absolute url in your .env . There may be a way to use relative urls, but there were some edge cases that just made it cleaner to use an absolute URL.
When you set this environment variable you want to make use of it in the following places:
Your Routes (if you use react router)
The path should be prefixed by process.env.PUBLIC_URL
Your internal links should also be prefixed by the env var.

How to redirect HTTP to HTTPS with Sails/React?

Current state: Depending on the npm start script, my web app is accessible by at the http:// address, or the https:// address, but not both.
Goal: I'd like the app to run on https://, and for any http:// requests to be redirected to https://.
App info: The web app is created with Sails for the server, and create-react-app for the UI. To run locally, I use two terminals to start each up (server on :1337, UI on :3000). To run in prod, I build the UI and copy the build into the server folder, then start the server on :84 (:80 already taken).
What I've tried:
I've tried adding redirection on the Sails server by adding middleware and policies.
I've tried adding redirection on the UI by adding a script in the HTML header, checking for window.location.protocol in index.js, adding to the http-proxy-middleware, and using react-https-redirect.
In all cases, I'm able to access the app if I go to the https:// address, but get err_empty_response from the http:// one. None of my http:// requests seem to even reach the app or server.
I've heard that using NGINX as a load-balancer may solve this, but I'm hoping for a solution that doesn't require as much set up. Any suggestions?

How do I change localhost:3000 to "custom.domain.dev" for a React app built with create-react-app for CORS

I am running into a CORS issue when trying to have my React app send post requests to an api endpoint while using localhost:3000.
How do I configure my app to use custom.domain.dev instead of localhost:3000?
I have /etc/hosts setup to to include 127.0.0.1 custom.domain.dev as well as my .env file to include HOST=custom.domain.dev.
As noted in this stackoverflow question,
Chrome does not support localhost for CORS requests (a bug opened in 2010, marked WontFix in 2014).
I think there are two parts of the question -
Regarding the CORS flag on local host
CORS flag is raised by the Browser when there is a request from a domain/port to an entire new domain/port. If you are doing this for testing, you can disable this security flag in chrome by adding the --disable-web-security flag. Just create a shortcut of chrome to desktop > Right click > Properties >In shortcut tab - Target > Append --disable-web-security --user-data-dir="C:\tmpChromeSession" to target. This will disable the CORS check.
In real cases, if you have access/control on the api server, what you should be doing is to enable CORS on server by adding necessary response headers (Access-Control-Allow-Origin) to the response. If you do not have access, one option will be to route the request through a CORS proxy.
Change port
You can change the running port of the react app on the package.json See this Stack Overflow answer. If you run the app on your machine, you are stuck with localhost.

How may implement subdomains using docker, a config file for nginx and building react on a container?

lovely people of SO,
I have this project where I'm doing a server based on node/express and using react in a small node container for the deployed site, everything is passed upon nginx for reverse proxy, i have searched for a way of using subdomains for my dashboard.example.com, but can't seem to work it out, no tutorials anywhere or code examples of how to achieve this, im no new to the MERN stack but nginx and docker.
I have tried using vhost, couldn't make it work as a subdomain, tried the npm express-subdomain, didn't work as expected either, how would you do this?
listen 8080;
location #LandingPage {
proxy_pass http://LandingPage:80;
}
# this one down here doesn't work as expected neither
location /gql/ {
proxy_pass http://server:1000/graphql;
}
}
had been mad last 2 weeks with the issue with the subdomain that I deleted all my middlewares and trash code that didn't get to work, please help
expected results:
dashboard.landingpage.com working and configured
bonus:
sending my queries to gql.landingpage.com, or landingpage.com/gql
actual results:
landingpage.com working on proxy
i just created this monster,
its an express app with a subdomain and an automatic build for the public folders, now i only need to proxy pass 1
https://github.com/sabasm/node-express-react-and-reactSubdomain/tree/master

Yeoman with grunt-connect-proxy returns a ECONNREFUSED error

I'm trying to add grunt-connect-proxy to a project that uses the latest yeoman + angular generator.
But, when hitting the road that should be forwarded (e.g. 127.0.0.1:9000/api/v1), the server returns this error:
An error has occurred: {"code":"ECONNREFUSED","errno":"ECONNREFUSED","syscall":"connect"}
I used a modified Gruntfile: same as here as recommended.
How I'm a supposed to debug this? Has anyone had a similar issue lately with grunt-connect-proxy?
I'm also interested in similar solutions for proxing api calls for an angular webapp, if you have any that actually work.
Thank you for helping me out! Much appreciated!
Gruntfile is fine, the error is caused by your backend, i.e. localhost:3000 (probably Rails).
If it is Rails, it's a CORS problem. You need to allow rails to accept connection from grunt server. Add 'rack-cors' to your gemfile and configure it like this in your development.rb config file:
config.middleware.use Rack::Cors do
allow do
origins 'localhost:9000'
resource '*', :headers => :any, :methods => [:get, :post, :options, :delete]
end
end
Check this link for detailed setup, it helped me to get it working.
Working with Angular.js and Rails
I was running into this issue while trying to develop locally using AngularJS with a Laravel backend.
I was able to get the grunt-conenct-proxy example working using the before mentioned Rails example: Working with Angular.js and Rails, however when trying to connect locally to my laravel backend I would always get the ECONNREFUSED error.
The only real difference I could see was that the rails server was spinning up on 0.0.0.0. where as my apache server was running on localhost/127.0.0.1. After changing my config for my apache sever to run at 0.0.0.0 using:
php artisan serve --host 0.0.0.0
I was the able to connect to my backed without issue. If anyone could comment and explain how/why this works I would be very grateful.
Well, I finally got it to work somehow.
But frankly, I don't get it. It was definitely related to localhost not being the same as 127.0.0.1. How did it ended that way, I don't have a clue...
I'll share what I learned while doing this, as I found no real answer for debugging this staff out there on the web. Here is what I learned:
grunt has a --verbose option that may help you see what's going on
If grunt-connect-proxy is configured correctly you must see something like this at startup:
Running "configureProxies" task
Proxy created for: /api/v1 to localhost:8000
In my case, the grunt server was running on 127.0.0.1:9000, the second server on localhost:8000. I proxied requests made on api/v1 so grunt server --verbose would output something like this on every proxied request:
Proxied request: /api/v1/test -> http://localhost:8000/api/v1/test
{
"host": "127.0.0.1:9000",
"connection": "keep-alive",
"accept": "...",
"user-agent": "...",
"accept-encoding": "...",
"accept-language": "...",
"cookie": "..."
}
the whole point of using a proxy is to avoid any unnecessary CORS configuration on your second server
This is because once deployed your frontend and backend code will coexist on the same server (= the grunt server is only needed at dev time). I wanted to stress that point, because #Ulugbek answer may suggest that you need CORS to make grunt-connect-proxy work.
the ECONNREFUSED error happens when your second server is not responding
In my case, I discovered that http://127.0.0.1:8000/api/v1/test was not responding even if http://localhost:8000/api/v1/test was. So, I messed around with the /etc/hosts a bit and solved the problem by making sure both endpoints were responding accordingly.
The same error may happen to you if the second server is not listening to the proxied endpoint.

Resources