Calling heroku API from React app, error 200 - reactjs

I created a small API that scrapes a web page for train arrival/departures. I hosted it on Heroku and when i visit the page: https://sl-scraper.herokuapp.com/fromstockholm i can see the JSON response i expect. It looks like this:
Everything fine so far. Now i am looking to get this data in my React app to display it in a nicer way. This is where i run into problem. I tried to get the information in two ways, and both ways causes the same issue.
Here is the first attempt:
React.useEffect(function(){
axios.get("https://sl-scraper.herokuapp.com/fromstockholm")
.then(response =>{
console.log(response);
})
.catch(err => console.log(err));
},[]);
Here is the second attempt:
React.useEffect(()=>{
fetch("https://sl-scraper.herokuapp.com/fromstockholm")
.then(response => {
return response.json();
})
.then(data => {
console.log(data);
})
.catch(error => console.log(error));
},[]);
Both these attempts causes this issue when i inspect the log:
Access to XMLHttpRequest at 'https://sl-scraper.herokuapp.com/fromstockholm' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Does anyone know why i get these errors? Thank you so much in advance.

Cloning the CORS-Anywhere repo to our PC
we have our environment set up we can proceed to clone the CORS-Anywhere repo into a selected destination on our PC.
As a developer, it is always nice to appreciate the effort of other developers that provide solutions that make our lives easier by sending some form of support in their direction, so do drop a star for the CORS-Anywhere repo if it helps you solve your problem.
To start, we will open our terminal at the directory of the local storage we want to place the CORS-Anywhere server in locally and run the git command:
git clone https://github.com/Rob--W/cors-anywhere/
After the cloning is complete we will have to install all the packages this project depends on by running the command npm install on your terminal:
npm install
After that deploy your heroku app.
Reference: https://dev.to/imiebogodson/fixing-the-cors-error-by-hosting-your-own-proxy-on-heroku-3lcb

Related

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

Error: Mixed Content, While Deploying React app on Github

I ran into a small problem while deploying a react app on GitHub pages. The app works perfectly fine on a live server. But, when I push the code on gitHub and test it. This error occurs:
Mixed Content: the page at '<domain>' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoing 'http://www.omdbapi.com/...' ...
I know it has something to do with the api I m using. It's omdb api and uses HTTP protocol for a get request. I tried changing the HTTP to https and though it works on the live server. It does not on the Github page, giving me the same error as before.
Code:
const apirul = 'http://www.omdbapi.com/?apikey=...';
// ...
Axios(apiurl + "&=s="+state.s)
.then(data => {
console.log(data);
let results = data.Search;
setState(prevState => {
return { ...prevState, results }
})
})
.catch(e => {
console.log(e)
})
// ...
Looking at the GitHub Pages and the source it's got, I suspect your push to GitHub failed as the code in the repo is still pointing to http://www.omdbapi.com/?apikey=ad5bdfd0 (and was last updated 17 hours ago). I took a screenshot to to confirm.
Changing it the URL to https:// should fix it, though you could use a protocol relative url (that is, //) if you had to. Really, you should be using https for everything now, even local development.

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