How to use a proxy for a link with reactjs - reactjs

I'm working on a website using Reactjs and Typescript for the front-end and the backend is in Java. While I'm developing I use port 3000 for the frontend and the 8080 for the backend. I have setup the proxy property on the package.json
"proxy": "http://localhost:8080"
so I don't have any problem while I'm doing requests to the backend because the proxy works perfectly.
Now I need to create some links to download reports, so I'm generating dynamically the links and I need them to point to the port 8080 and not to the port 3000
I'm passing the url like:
<a href={this.state.url}>Download Report</a>
where this.state.url looks like /reports/download/users and make sense its pointing to http://3000/reports/download/users
Any idea how to create the links in dev to point to the port 8080.
Updated
The proxy is working with a request like the below code:
fetch('./app/admin/reports/availableReports')
.then(res => res.json())
.then(json => json.reportTypes)
.catch(ex => {
console.log('Alert!!', ex)
return []
})
But its not working when I generate a url link:
<a href={'app' + this.state.currentDownloadUrl}>Download Report</a>

I used one not a very good solution I think, but it works for me.
<a href={`http://localhost:8000${record_detail_item.file}`} download>Download File</a>
You can have some global variable which points to your dev server and you can use it instead of http://localhost:8000
Update:
Instead of hardcoding URL, you can set up environment variables Create-react-app environment variables

You shouldn't use the proxy property to set the backend base url. As per the doc:
Keep in mind that proxy only has effect in development (with npm start), and it is up to you to ensure that URLs like /api/todos point to the right thing in production.
When you build your app, it won't work.
You should add an environment variable for your backend base URL and prepend it when you make backend calls.
Something like
fetch(`${process.env.REACT_APP_API_ENDPOINT}/app/admin/reports/availableReports`)
.then(res => res.json())
.then(json => json.reportTypes)
.catch(ex => {
console.log('Alert!!', ex)
return []
})
<a href={`${process.env.REACT_APP_API_ENDPOINT}${this.state.currentDownloadUrl}`}>Download Report</a>

Related

React CRA: When adding subdomain on localhost it says: The development server has disconnected

I am on a project with create-react-app without ejecting.
I wanted to have subdomains on localhost or a fake host for development.
When I added my host in windows hosts file it said invalid host header even if I add HOST=mydevhost.com DANGEROUSLY_DISABLE_HOST_CHECK=true in .env file.
I couldn't make it work without using third party apps so I used Fiddler and it worked as expected now the sites comes up but instantly says:
The development server has disconnected.
Refresh the page if necessary.
The problem is that the fast refresh doesn't work now and I have to refresh the site every time I make a change. Is there anything that I'm doing wrong here? Should I even use something like Fiddler here?
I ended up using react-app-rewired and in config-overrides.js I added the subdomain to allowed host. The final config looks like this:
module.exports = {
webpack: (config, env) => {
return config;
},
devServer: (configFunction) => (proxy, allowedHost) => {
const devServerConfig = configFunction(proxy, allowedHost);
devServerConfig.allowedHosts = ["subdomain.localhost"];
return devServerConfig;
},
};
I thing you can do that from your operating system to point your local domain to your react server, meaning that can create a local domain that points to the app server (host:port).
here's a guideline that may help:
https://www.interserver.net/tips/kb/local-domain-names-ubuntu/
Relevant answers:
How can I develop locally using a domain name instead of 'localhost:3000' in the url with create-react-app?

How do I configure my React-Node App so I can deploy it to Heroku?

So I've built a simple MERN app using create-react-app, that I want to deploy to Heroku. I build the front end in a client folder operating on localhost:3000, that sends requests to my express sever as a proxy to localhost:5000. My file structure is as follows:
+client
|
+-node_modules
+-public
+-src
|
+-components
+-App.js
+-index.js
//server
+-models
+-node-modules
+-package-lock.json
+-package.json
+-server.js
And I've set up the proxy in my package-json like this: "proxy": "http://localhost:5000",
So my main question is this: How do I configure my API endpoints for deployment?
At the moment, they're structured like this:
API call from react component:
useEffect(() => {
axios.get("http://localhost:5000/api/all-cafes")
.then((cafe) => {
setCafe(cafe.data);
})
.catch((err) => {
console.log(err);
})
}, [])
Express function on server.js
app.get('/api/all-cafes', (req,res) => {
Cafe.find()
.then((result) => {
res.send(result)
})
.catch(err => {
console.log(err)
})
})
My other question is what is the role of the .env file, and will I need to make one in order to solve this?
I've had a helpful suggestion saying that I can run the front end and back end on different servers, and adjust the code depending on whether it is in development or production, using the following code:
const prefix = process.env.NODE_ENV === 'production' ? "http://heroku_app_address" : "http://localhost:5000"
function getUrl(relativeUrl) {
return prefix + "/" + relativeUrl;
}
fetch(getUrl('api/all-reviews'));
But I'm not sure how to implement this, whether I need a .env file, and if so, what to put in said file.
The .env file helps you specifiy certain credentials or endpoints that are either going to change based on deployment environment (dev,qa,prod may have differewnt API endpoints), or you want to provide certain secret keys or configurations, which otherwise should not be part of your code repository (clientSecret etc).
The create-react-app.dev/docs has detailed explanation to these.
If you have not bootstraped your app using create-react-app then you can use dot-env npm package. The steps are detailed here: Stack overflow :Adding an .env file to React Project

How to fix 431 Request Header Fields Too Large in React-Redux app

I'm working through a MERN sign up/login auth tutorial on youtube that uses Redux. When attempting to POST a test user to the server in Postman, I receive the 431 header request is too large error response.
I've read in some places that clearing the cache/history in your browser works, so I've tried that to no avail. I've also added in a "Clear-Site-Data": "*" entry to the header request (in addition to "Content-Type": "application/json") which hasn't worked, either.
Client Side Code for Sign Up
onSubmit = e => {
e.preventDefault();
const { name, email, password } = this.state;
const newUser = {
name,
email,
password
};
this.props.register(newUser);
};
//redux actions
export const register = ({ name, email, password }) => dispatch => {
const config = {
headers: {
"Content-Type": "application/json",
"Clear-Site-Data": "*"
}
};
// Request body
const body = JSON.stringify({ name, email, password });
axios
.post('/api/users', body, config)
.then(res =>
dispatch({
type: REGISTER_SUCCESS,
payload: res.data
})
)
.catch(err => {
dispatch(
returnErrors(err.response.data, err.response.status, 'REGISTER_FAIL')
);
dispatch({
type: REGISTER_FAIL
});
});
};
The user sign up should be sending a name, email and password to my connected Mongo db, however, it halts me and redux hits the REGISTER_FAIL type I created returning the 431 error. Any help would be greatly appreciated. Thank you!
I had faced the same issue in my Angular Application. After spending a lot of time, I had found out that the issue is related with Node JS. We were using Node JS v12.x.x, and in this version, max-http-header-size reduced to 8KB from 80KB. And the auth token which I had was of around 10KB. That's why, when I reload the app, browser starts giving '431 request header fields too large' error for some of the files. I had updated the Node JS v14.x.x and it starts working again because in v14.0.0, max-http-header-size has been increased to 16KB.
Hope it will be helpful.
Another suggestion would be to access your cookies, in the inspector tool, and delete. applicable cookies for your localhost:{port} application.
I had similar problems with just using localhost(not limited to redux). Maybe this might help.
Put this into url: chrome://settings/?search=cache
Click on Clear Browsing data.
Tick cookies and other site data (Important since cookies is in HTTP header)
TIck cached images and files (might be optional)
Not reactjs, but using vue-cli, for people like me, just being stupid it may help:
I started my Vue app on port 8080, and my local backend was running at port 4000. However my requests pointed to 8080 and the response I got from Webpack Serving was "431 Request Header Fields Too Large".
The plain solution was just to use the right backend-port. Even though that was a really stupid mistake of me, the error message is kinda useless here.
It means you are trying to do this fetch on your current front-end development server. You need to specifiy the server address. For example:
.post('/api/users', body, config)
should read
.post('http://localhost:4000/api/users', body, config)
Another fix would be to change the line proxy in your package.json from localhost:3000 to localhost:4000 assuming that 4000 is your actual server port.
The issue I was having is that I was trying to access a file in the src directory. The fix is to move it to the public directory and it now works fine.
E.g.
From
public
- index.html
- favicon.ico
- etc
src
> access-me
- App.tsx
- etc
to
public
> access-me
- index.html
- favicon.ico
- etc
src
- App.tsx
- etc
Is it from Brad Travery's course? Check "proxy" in package.json, or try using full url in axios request. I had to completely restart server after changes, bc it's still use the old port (btw, I was enter wrong port)
Fixed in https://stackoverflow.com/a/56351573/9285308
(the max http header size parameter is configurable):
node --max-http-header-size 16000 client.js
In my react app, I add --max_old_space_size flag and it is worked. Current start script is :
"start": "react-scripts --expose-gc --max_old_space_size=12000 start",
Just change your start script in package.json file and you are good to go.
"start": "react-scripts --max-http-header-size=1024 start",
NextJS solution:
https://stackoverflow.com/a/73136780/6725458
"dev": "concurrently next dev node --max-http-header-size=64555 api-server"
Just found a solution:
NETCORE 6.0 / React template VS 2022
You have to setup the proxy url in package.json with the value of your url asp net application!
AspNet URL in debug console
So you can have that 431 error when you use the proxy of default React/AspNetCore project and you don't setup a proxy url (or a valid one) in the package.json.
proxy url in package.json
I had this problem when I accidentally created a proxy to the frontend itself by mixing up the port.
I had a backend on port 5000 and create-react-app on port 3000.
I put
"proxy": "http://localhost:3000",
in the package.json. This is clearly a mistake as it leads to infinite recursion by querying the react app over and over.
I fixed it (obviously) by putting the correct port number
"proxy": "http://localhost:5000",
Port numbers in your particular case might vary of course, just put this answer here for completess sake.

Opening up Rails API to users within a closed network

I am attempting to run a React/Rails Website locally for 2-3 users within a closed network. Currently, the users can reach the React portion (I have that set to port 80). The problem is, the API calls I have set to my Rails backend are all on localhost:3001 and the users have zero access to that database when I try to submit HTTP requests.
I know it's a CORS issue but I thought the code below would allow any domain to make the necessary request.
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '*',
headers: :any,
methods: [:get, :post, :put, :patch, :delete, :options, :head]
end
end
Server side work is not my forte, so I may be missing something glaring. Any idea how to open up that backend so the networked users can make API Calls on their end?
React is on this ip: http://192.168.2.70:80/
API calls on this port: 3001
Example API call from front end (works on host computer; not on other users):
getData = () => {
axios.get('http://localhost:3001/api/v1/pickup_deliveries')
.then((response) => {
this.setState({
apiData: response.data})
})
.catch((error)=>{console.log(error);});
}
The Problem
Unless I missed something, it looks like you're making a simple mistake that you're going to smack yourself for.
Typically, a CORS issue in a JavaScript application would yield a CORS/pre-flight request error error in your browser's JavaScript console.
The Misconception
The JavaScript that makes up a React application is downloaded by the client (i.e. your users). After that, the fetch call is executed on the client's computer. The fetch request doesn't originate from the server, but rather from the remote end.
It works on your computer because both React and the Rail API are hosted on your computer, so localhost:3001 resolves correctly. However, on your users computer, the React app attempts to find a service running on port 3001 on their computer.
Initial Solution
You need to tell React to reach out to the IP server that's hosting the API, like this:
getData = () => {
axios.get('http://192.168.2.70:3001/api/v1/pickup_deliveries')
.then((response) => {
this.setState({
apiData: response.data})
})
.catch((error)=>{console.log(error);});
}
Long Term Solution (for deployment)
In the future, look into dotenv, which will allow you to set React environment variables. You could have a .env.local file, and a .env.production file.
In the local file, you could put:
REACT_APP_BACKEND_SERVER=http://localhost:3001
and in the production on you could put:
REACT_APP_URL=http:/<server_ip>:3001
Then, in your program, do something like:
getData = () => {
axios.get(process.env.REACT_APP_SERVER_URL + "/api/v1/pickup_deliveries")
.then((response) => {
this.setState({
apiData: response.data})
})
.catch((error)=>{console.log(error);});
}
This will automatically resolve to localhost when serving React using npm run start and then resolve to <server_ip> when you are serving the static files generated by npm run build.
Feel free to comment on this answer. I would be happy to answer any other questions you have. Welcome to React!

React Native fetch a local server using a proxy

In my react native app I am trying to perform a fetch to my local backend server. In my package.json I have put "proxy": "http://localhost:3000" .
My fetch looks like
fetch('/')
.then(response => response.json())
.then(json => console.log(json))
.catch(err => console.log)
It catches an error
[TypeError: Network request failed]
When I remove the proxy and manually enter the address in the fetch it works and my server receives a GET request.
fetch('http://localhost:3000')
.then(response => response.json())
.then(json => console.log(json))
.catch(err => console.log)
Two points here:
Set proxy in package.json is a feature of create-react-app, which wraps webpack dev server's proxy. react-native uses Metro instead of Webpack as bundler and it does not support setting up a local proxy.
Different from the web, http client in react-native has no current host. So if you use fetch('/'), it won't know which domain or ip address to send request to.
hello you can use your network IP Address for using local server like instead localhost change with your Ip address and you can call your server e.g, http://192.xxx.x.xxx:3000

Resources