I am trying to fetch some data from the development server using React.
I am running the client on localhost:3001 and the backend on port 3000.
The fetch request :
const users = fetch('/api/users');
users.then((err,res) => {
console.log(res);
})
When I run my development server and webpack-dev-server I get the following output:
GET http://localhost:3001/api/users 404 (Not Found)
I tried specifying the proxy in the package.json so it would proxy the request to the API server, however nothing has changed.
Here is my package.json file:
.. and the webpack.config :
Please tell me, if you need to see anything else from my project. I apologies, if I'm missing something and not being thorough, I'm still quite new to using these technologies.
You can modify your fetch request API url to give the complete hostname since
fetch('http://localhost:3000/api/users')
also make sure that you have CORS enabled on your backend
In case your want to redirect through webpack, your can try devServer.proxy as
devServer: {
inline: true,
contentBase: './dist',
port: 3001,
proxy: { "/api/**": { target: 'http://localhost:3000', secure: false } }
}
I know I'm a little late to the game here, but I'll leave it here for future reference.
To make the devServer proxy work as expected, you need to specify the HTTP Accepts header to be something else than "text/html". Do this with the init-object that fetch accepts as the second argument. A simple example:
fetch("/api/profile",{
headers:{
"accepts":"application/json"
}
})
.then(res => {
console.log(res);
return res.json();
})
.then(json => console.log(json) )
.catch( a => { console.log(a) });
The reason for this is that the WebPack Dev Server normally uses a context/namespace to differentiate between what to serve and what to forward. The create-react-app scripts do not extract a namespace from the proxy path in the package.json file. Instead the scripts has the opinionated default behaviour that any request using something else than HTTP GET will get forwarded. Also, anything using HTTP GET, but NOT text/html as the Accepts header will get forwarded.
The reasoning is because most React Apps are SPA (Single Page Applications) which use AJAX/Fetch to communicate with some API. API's normally use JSON or XML, but not text/html.
In the package.json
"proxy": {
"/api/users": {
"target": "http://localhost:3000"
}
},
I had the same problem using axios and was only able to get it working by using the complete hostname and enabling Cors.
const response = await axios.get('http://localhost/users/');
Install cors
npm i cors
Use cors
const express = require("express");
const request = require("request");
const cors = require("cors");
const app = express();
app.use(cors());
app.use("/", (req, res) => {
//...
});
app.listen(80, () => {
console.log("CORS-enabled web server listening on port 80");
});
Ref
The solution by user jellyfish-tom in https://github.com/webpack/webpack-dev-server/issues/793#issuecomment-316650146 worked for me.
devServer: {
proxy: {
"*": "http://[::1]:8081"
// "secure": false,
// "changeOrigin": true
}
},
Webpack Dev Server uses devServer.proxy config in your Webpack config to control proxying requests.
Related
I'm currently trying to proxy my requests from my Vue app so I can send cookies back from the server that exists separate from my frontend.
I have my frontend on port 8080 and server on port 3000. However, when I try to configure my proxy to use port 3000 in Vue using devServer.proxy, it sends the request to 8080 still.
Here is my code in vue.config.js:
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'https://localhost:3000',
ws: true,
changeOrigin: true
}
}
}
}
Here is my axios request:
axios.post(`/api/auth/login/`, loginDetails, {
withCredentials: true,
credentials: 'include'
})
.then(function (response) {
console.log('login response: ', response)
})
.catch(error => {
console.error(error)
});
Here is the error I get that shows the frontend is still sending to 8080:
I also tried using the following in vue.config.js and not having anything prefixed to the request url, but to no avail.
module.exports = {
devServer: {
proxy: 'http://localhost:3000'
}
}
Here is the documentation that I am using https://cli.vuejs.org/config/#devserver
Solution:
After taking a look at the server logs, I found out that the proxy was working and it was trying to find the /api/auth/login route on my server. However, I only had /auth/login so the server sent the 404 status.
I'm not sure if this is the correct way to do this, but I simply prepended the server route with /api and it worked like so:
app.use('/api/auth', authRouter)
Previously it looked like this:
app.use('/auth', authRouter)
Thank you to Estus Flask for the tips in the comments.
I'm trying to build a simple web app using the MERN stack while following a course.
My backend runs on port 5000 while react runs on port 3000. When I want to make a request with the backend API, it sends it to port 3000 instead of 5000. I keep on getting this error message:
xhr.js:178 POST http://localhost:3000/api/users 400 (Bad Request)
I included "proxy" : "http://localhost:5000" in my package.json. I tried replacing 'localhost' with 127.0.0.1. I tried deleting and reinstalling the package-lock.json and node_modules folders. I tried removing the proxy and using the entire url. I tried installing http proxy middleware. I tried enabling CORS on the backend too.
Either I'm cursed or doing everything wrong.
I'm using axios for handling the requests, here's the code.
const config = {
headers: {
'Content-type': "application-json"
}
}
const body = JSON.stringify(newUser)
const res = await axios.post('/api/users', body, config)
console.log(res.data)
Definetely not a proxy issue. The problem might be that you're passing the body as a JSON string to the axios post() method. No need to do that, just pass the object:
const res = await axios.post('/api/users', newUser, config)
Also, the correct value for Content-type is application/json (not application-json)
Try to add the base url to axios config :
const config = {
headers: {
'Content-type': "application-json"
}
baseURL: 'http://localhost:5000',
}
This is my middleware file known as setupProxy.js.
I have my express server running on port 5000, I also have my app using '/todos';
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
console.log('Proxy setup');
app.use(
'/testing',
createProxyMiddleware({
target: 'http://localhost:5000/todos',
changeOrigin: true,
})
);
};
I do an api call
await axios.get('/testing/home', {validateStatus: false})
.then(async (response) => {
}
This throws an error
GET http://localhost:5000/testing/home 404 (Not Found)
Why is my proxy not pushing /testing/home to localhost:5000/todos/home?
I have the setupProxy.js file in the src folder, the package json is separated from my servers package.json file. Am I supposed to proxy from the backend instead of the front-end or something? I can get all normal requests for /todos/* from my front-end so it just seems like the proxy isnt working at all.
I have two servers running in my backend, because of that I have to use the http-proxy-middleware package but I am encountering some problems.
This is my code in the frontend which is running on localhost:3000
axios("/api2/login",data)
.then((res) => {
});
This is my code in the backend which is running on localhost:5001
const { createProxyMiddleware } = require('http-proxy-middleware');
app.use(createProxyMiddleware('/api2', {target: 'http://localhost:5001', changeOrigin: true}))
app.post("/login", (req, res, next) => {
res.send("Logged In");
});
This code is no working showing this error in the browser's console
GET http://localhost:3000/api2/login 404 (Not Found)
Uncaught (in promise) Error: Request failed with status code 404
at createError (createError.js:16)
at settle (settle.js:17)
at XMLHttpRequest.handleLoad (xhr.js:61)
I am not able to understand where I am going wrong.
Looks like it's hitting localhost:3000 instead of localhost:5001 which is where your server is running from.
axios("http://localhost:5001/api2/login",data)
.then((res) => {
});
You can also set the baseURL in axios. HTTP get request with Axios gets sent with the local host IP at the beginning of the URL
If I understand correctly your server is listening on port 5001. So, you need to proxy your requests from 3000 to 5001. You can do that in the react application by setting the proxy value in package.json:
"proxy": "http://localhost:5001",
For more information about this subject, check the docs.
Edit for the configuration explained in the comment section
First in package.json:
"proxy": "http://localhost:5002",
Create a new server (proxyserver) which will be listening in port 5002:
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const app = express();
// redirection for first server 5000
app.use('/api1', createProxyMiddleware({ target: 'http://localhost:5000', changeOrigin: true }));
// redirection for second server 5001
app.use('/api2', createProxyMiddleware({ target: 'http://localhost:5001', changeOrigin: true }));
app.listen(5002);
For the other servers (5000 and 5001) you don't need to redirect the requests. Just make sure they're listening on the right ports (5000 and 5001), for example:
const express = require('express');
const app = express();
app.post("/api2/login", (req, res, next) => {
res.send("Logged In");
});
app.listen(5001);
I followed the steps mentioned in this post along with some changes,
I changed my Axios request code to:
axios({
method: "POST",
data: user,
withCredentials: true,
url: "/api2/login",
}).then((res) => {})
Otherwise, the proxy server was treating it as a GET request.
Secondly, I changed the proxy endpoint code int the proxy server as:
app.use('/api2', createProxyMiddleware({
target: 'http://localhost:5001',
changeOrigin: true,
pathRewrite: {
[`^/api2`]: '',
},
}));
Further information about the proxy endpoint change can be found here.
I'm building an app with create-react-app.
I have local Apache server running on port 80 to execute my backend API PHP scripts.
I have added
"proxy": "http://localhost:80" to my package.json,
but on this axios requests:
getAllCategories = () => {
const url = process.env.PUBLIC_URL+`/api/api/categories/categories.php`;
axios.get(url)
.then(res => {
const categories = res.data.data;
this.setState({ categories });
}).catch(err => {
console.log('Axios fetch error:',err);
})
}
My request are directed to
Request URL: http://localhost:3000/api/api/categories/categories.php
according to Chrome Devtools and I'm not getting the data required.
In the build mode on remote server everything works fine with those paths indicated.
How can I configure proxy in dev mode to access my API files?
Have you tired path like this?
axios.get(`/api/api/categories/categories.php`)
...
If you are using create-react-app install http-proxy-middleware as a dev dependency and in your src folder create a file called setupProxy.js (it must be spelt exactly like that).
In that file:
const proxy = require('http-proxy-middleware');
module.exports = function(app) {
app.use(proxy('/api', { target: 'http://localhost:80' }));
};
You will need to restart the app for it to take effect.
Your api calls should not need the process.env