Invalid URI when making a request to backend with create-react-app - request

I am making a ReactJS front-end app, using create-react-app, I have set up my proxy and made sure it is working by testing with a REST API client (Insomnia). For some reason, when the request is made from the browser, it fails with status code 500, and the reason given is "Ivalid URL". I have tried it using a different browser on the development machine, deleting the node_modules folder, used to different request libraries, even reinstalling create-react-app and creating the project structure from scratch, but I can't seem to get it to work. The weirdest part of all is that the app works as written on my laptop.
I have set up my proxy like this:
const proxy = require ('http-proxy-middleware');
module.exports =function (app){
console.log("Se ejecutó el setupProxy");
app.use(proxy("/register", {target:"http://localhost:3001"}));
app.use(proxy("/auth/local", {target:"http://localhost:3001"}));
app.use(proxy("/api/current_user", {target:"http://localhost:3001"}));
}
My request from the front end, made in one of my Redux Action Creators looks like this:
export function registerUser(userInfo)
{
return async (dispatch) =>
{
/*axios.post("/register",{
display_name: userInfo.username,
password: userInfo.password,
email: userInfo.email,
}).then((resp)=>{
dispatch({type: USER_REGISTRATION, payload:"User Registered"});
}).catch((error)=>{
dispatch({type: USER_REGISTRATION,payload:error.response.data.message});
});*/
rp.post('/register',{json:true,formData:{
display_name: userInfo.username,
password: userInfo.password,
email: userInfo.email
}}).then((response)=>{
console.log(response);
}).catch((err)=>{
console.log("Error ha ocurrido:");
console.log(err);
});
};
}
Notice that I have tried with both axios and request.js. Axios does not return a body, and Request.js simply returns a status code 500 and an Invalid URL message.
What am I doing wrong? Why does this work on one machine, but not in another? Please, I am at my wit's end with this. If anyone can help, it would be greatly appreciated.

With create react app you can add a proxy property to your package.json. No need to use a third party library.
package.json
{
"name": "your-app",
"version": "0.1.0",
"private": true,
"proxy": "localhost:3001", //this is your back end port
More info can be found here: https://facebook.github.io/create-react-app/docs/proxying-api-requests-in-development

I was able to solve this by cloning my repository from scratch on a different folder and installing the dependencies again into the new copy. I still don't know why this happened, but this solved it.

Related

NextJS getServerSideProps() "unable to verify the first certificate", "UNABLE_TO_VERIFY_LEAF_SIGNATURE"

I'm new to NextJS, I recently converted my ReactJS project to it and it worked fine. However I was still using useEffect to retrieve data. Now I'm trying to use getServerSideProps() instead, as is recommended by NextJS, but it's giving me problems.
This is my getServerSideProps()
export async function getServerSideProps() {
const res = await axios.get(`BACKEND_URL/product/0`);
const data = await res.data;
return { props: { data } };
}
The API call works when I use it in React's useEffect but using the function getServerSideProps() it's giving me status 500 "UNABLE_TO_VERIFY_LEAF_SIGNATURE"
"message":"unable to verify the first certificate",
"stack":"Error: unable to verify the first certificate\n
at TLSSocket.onConnectSecure (_tls_wrap.js:1515:34)\n
at TLSSocket.emit (events.js:400:28)\n
at TLSSocket._finishInit (_tls_wrap.js:937:8)\n
at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:709:12)",
"code":"UNABLE_TO_VERIFY_LEAF_SIGNATURE","status":null}
Does anyone know what it can be? My backend is accessible I checked, the url works. When I don't use getServerSideProps() the page works.
I can work around this issue by adding the following to _app.js
axios.defaults.httpsAgent = new https.Agent({
rejectUnauthorized: false,
});
But apparantly this isn't safe to do.
It was a problem with the SSL certificate. I was using the self-made one but you need the CA certificates.
I made a file with the CA certificates that I get in my Plesk panel, then I added this line in Apache and now it's fixed.
SSLCertificateChainFile C:/Users/Administrator/Desktop/cert/ca-cert.crt
This is usually not mentioned in Apache guides so hopefully I can help someone else with this solution. :)

NextJs: The Serverless Function exceeds the maximum size limit of 50mb

I'm new working with NextJs and when trying to deploy my project to Vercel I'm getting the following error:
Error! The Serverless Function "api/auth" is 50.55mb which exceeds the maximum size limit of 50mb.
I have spent a lot of my time trying to find a proper answer but I didn't find any. Here is the code of the api request I'm making:
const { auth: adminAuth } = require("firebase/admin");
export default async function auth(req, res) {
const tokenId = req.query.token;
return new Promise((resolve) => {
adminAuth
.verifyIdToken(tokenId)
.then((user) => {
res.json(user);
resolve();
})
.catch(() => {
res.status(302).send("Invalid authentication");
resolve();
});
});
}
I'll be really grateful if anybody can help me, thanks y'all!
I've been dealing with the same issue. It appears that when bundling the serverless function vercel is pulling in ALL assets within your project. So 50.55MB is likely the size of your current entire build. I'm researching how to only include certain files within the vercel.json but have so far not figured exactly how to do that. For now you could probably just remove a few files from your public assets to get under the limit.
This is likely caused by firebase/admin including everything in the firebase package, not just the "admin" parts.
You can verify this by creating a file with only the import and running #vercel/nft to trace the files.
npm init -y
npm add firebase
echo "const { auth: adminAuth } = require('firebase/admin')" > index.js
npm i -g #vercel/nft
nft print index.js
The entire firebase package is quite large, so its best to follow the recommendation from the firebase team and use the firebase-admin package inside Serverless Functions.
This SDK (firebase) is intended for end-user client access from environments such as the Web, mobile Web (e.g. React Native, Ionic), Node.js desktop (e.g. Electron), or IoT devices running Node.js. If you are instead interested in using a Node.js SDK which grants you admin access from a privileged environment (like a server), you should use the Firebase Admin Node.js SDK (firebase-admin).
source: firebase NPM
You could add .vercelignore file to avoid this
Ref: https://vercel.com/guides/prevent-uploading-sourcepaths-with-vercelignore
# Ignore everything (folders and files) on root only
/*
!api
!vercel.json
!*.html
!*.css

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!

Resources