I'm having issues with the proxy I set up.
This is my root package.json file:
"scripts": {
"client": "cd client && yarn dev-server",
"server": "nodemon server.js",
"dev": "concurrently --kill-others-on-fail \"yarn server\" \"yarn client\""
}
My client package.json file:
"scripts": {
"serve": "live-server public/",
"build": "webpack",
"dev-server": "webpack-dev-server"
},
"proxy": "http://localhost:5000/"
I've set up express on my server side to run on port 5000. Whenever I make a request to the server, ie :
callApi = async () => {
const response = await fetch('/api/hello');
const body = await response.json();
// ... more stuff
}
The request always goes to
Can someone point out what i have to do to fix this issue so that the request actually goes to port 5000?
I experienced this issue quite a few times, and I figured it's because of the cache. To solve the issue, do the following
Edit: #mkoe said that he was able to solve this issue simply by deleting the package-lock.json file, and restarting the app, so give that a try first. If that doesn't resolve it, then do the following.
Stop your React app
Delete package-lock.json file and the node_modules directory by doing rm -r package-lock.json node_modules in the app directory.
Then do npm install in the app directory.
Hopefully this fixed your proxy issue.
The reason the react application is still pointing at localhost:8080 is because of cache. To clear it , follow the steps below.
Delete package-lock.json and node_modules in React app
Turn off React Terminal and npm install all dependencies again on React App
Turn back on React App and the proxy should now be working
This problem has been haunting me for a long time; but if you follow the steps above it should get your React application pointing at the server correctly.
This is how I achieved the proxy calls.
Do not rely on the browser's network tab. Put consoles in your server controllers to really check whether the call is being made or not. For me I was able to see logs at the server-side. My node server is running on 5000 and client is running on 3000.
Network tab -
Server logs -
Check if your server is really running on the same path /api/hello through postman or browser. For me it was /api/user/register and I was trying to hit /api/user
Use cors package to disable cross-origin access issues.
Is your client being loaded from http://localhost:8080?
By default the fetch api, when used without an absolute URL, will mirror the host of the client page (that is, the hostname and port). So calling fetch('/api/hello'); from a page running at http://localhost:8080 will cause the fetch api to infer that you want the request to be made to the absolute url of http://localhost:8080/api/hello.
You will need to specify an absolute URL if you want to change the port like that. In your case that would be fetch('http://localhost:5000/api/hello');, although you probably want to dynamically build it since eventually you won't be running on localhost for production.
For me "proxy" = "http://localhost:5000 did not work because I was listening on 0.0.0.0 changing it to "proxy" = "http://0.0.0.0:5000 did work.
Make sure you put it on package.json in client side (react) instead of on package.json in server-side(node).
This solution worked for me, specially if you're using webpack.
Go to your webpack.config.js > devServer > add the below
proxy: {
'/api': 'http://localhost:3000/',
},
This should work out.
Read more about webpack devSever proxy: https://webpack.js.org/configuration/dev-server/#devserver-proxy
I have tried to solve this problem by using so many solutions but nothing worked for me. After a lot of research, I have found this solution which is given below that solved my proxy issues and helped me to connect my frontend with my node server. Those steps are,
killed all the terminals so that I can stop frontend and backend servers both.
Installed Cors on My Node server.js file.
npm install cors
And added these lines into server.js file
var cors = require('cors')
app.use(cors())
Into package.json file of frontend or client folder, I added this line,
"proxy" : "http://127.0.0.1:my_servers_port_address_"
Now everything working fine.
Yours might not be the case but I was having a problem because my server was running on localhost 5500 while I proxied it to 5000.
I changed my package.json file to change that to 5500 and used this script:
npm config set proxy http://proxy.company.com:8080
npm config set https-proxy http://proxy.company.com:8080
I am pretty sure just changing it on the package.json worked but I just wanted to let you know what I did.
you should set the proxy address to your backend server, not react client address.
you should restart the client after changing package.json
you should use fetch('/api/...') (instead of fetch('http://localhost:8080/api/'))
Make sure you check your .env variables too if you use them. It's because of that if I was looking for a solution on that page.
I tried all the solutions, proposed here, but it didn't work. Then I found out, that I tried to fetch from root directory (i.e. fetch('/')) and it's not correct for some reason. Using fetch('/something') helped me.
Your backend data or files and react build files should be inside the same server folder.
you must give proxy after the name.{"name":"Project Name", "proxy":"http://localhost:5000"}
port should match with your backend's port.
If you are seeing your static react app HTML page being served rather than 404 for paths you want to proxy, see this related question and answer:
https://stackoverflow.com/a/51051360/345648
(This doesn't answer the original question, but searching Google for that question took me here so maybe this will help others like me.)
In my specific case, I had a both Node backend, and an inner folder with a React project. I tried #Harshit's answer, which didn't work, until I had two package.json files in my project, one in the outer folder, and one in my client (React) folder. I needed to set up the proxy in the inner package.json, and I needed to clear the cache in the inner folder.
I was having this issue for hours, and I'm sure some of the things above could be the cause in some other cases. However, in my case, I am using Vite and I had been trying to add my proxy to the package.json file, whereas it should be added to the vite.config.js file. You can click here to read about it in Vite's docs.
In the end, my code looks like this:
export default defineConfig({
server: {
proxy: {
"/api": {
target: "http://localhost:8000",
secure: false,
},
},
},
plugins: [react()],
});
My problem was actually the "localhost" part in the proxy route. My computer does not recognize "localhost", so I swapped it with http://127.0.0.1:<PORT_HERE> instead of http://localhost:<PORT_HERE>.
Something like this:
app.use('/', proxy(
'http://localhost:3000', // replace this with 'http://127.0.0.1:3000'
{ proxyReqPathResolver: (req) => `http://localhost:3000${req.url}` }
));`
For me, I solved this by just stopping both the servers i.e. frontend and backend, and restarting them back again.
Here is an opinion
Don't use proxies, use fetch directly
not working
fetch("/signup", {
method:"post",
headers:{
"Content-Type":"application/json"
},
body:JSON.stringify(
{
name:"",
email:"",
password:"",
}
)
Actually worked after wasting 6hours
fetch("http://localhost:5000/signup", { // https -> http
// fetch("/signup", {
method:"post",
headers:{
"Content-Type":"application/json" },
body:JSON.stringify(
{
name:"",
email:"",
password:"",
}
)
In my case the problem was that the proxy suddenly stopped to work.
after investigating I found that I've moved the setupProxy from the src folder and that cause the problem.
Moving it back to the src folder have solved the problem.
The problematic structure:
The solution:
faced similar issue. my proxy was not connecting restarting the react app fixed my issue
In my case it was because of typo. I wrote "Content-type": "application/json", (with small t) instead of "Content-Type": "application/json",
you should install this package:
npm install http-proxy-middleware --save
refrense: this link
Make sure your end point match with the backend.
I am running the webpack / webpack-dev-server portion of the base Vue.js Webpack template (https://github.com/vuejs-templates/webpack/) inside of a docker container I created. The container also contains the vue CLI in order to create new projects (you can get my container here if you want: https://hub.docker.com/r/ncevl/webpack-vue/).
Hot-reload does not work after moving from the webpack-simple template to this one.
Everything was working using the Webpack-Simple template which you can clone / see over here: https://github.com/vuejs-templates/webpack-simple
I was able to get the simple template running (with hot-reload working as intended) with the following webpack-development-server launch command:
webpack-dev-server --hot --inline --progress --host 0.0.0.0 --watch-poll
That said the full (not simple) version of the webpack template does not appear to use a webpack-dev-server launch command and instead appears to use additional middleware as referenced in build/dev-server.js (https://github.com/vuejs-templates/webpack/blob/master/template/build/dev-server.js) and the webpack dev config.
Since the --watch-poll was the key to getting the WDS hot-reload functionality to work within a docker container in the last project, my thinking is that I need to do something similar with the webpack-hot-middleware but I dont see anything in their docs (over here: https://github.com/glenjamin/webpack-hot-middleware) that talks about changing to a polling based approach.
I am not 100% sure the polling flag will do the trick since I can see the container recompile my source when I make a change. I can also see the change in my browser if I refresh it manually.
Whats stranger still is if I inspect my page in browser within chrome dev tools, and then head over to network / XHR I can see that the browser actually does receive information from the webpack-dev-server, but visually it does not update.
Give the above I assume websockets (or socket.io which I think is used) are working and communicating between the browser and the WDS so maybe this is a browser caching issue of some sort?
I checked in my console and found this so it is looking like a header issue:
For reference the text error from that image (to make it easier for anyone having the same issue to find this post) is:
EventSource cannot load http://__webpack_hmr/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://0.0.0.0:8080' is therefore not allowed access.
Again the Hot-Reload / Hot Module Reload was working with this identical container setup when using the webpack-simple Vue.js template.
I am wondering if anyone has run into anything similar or has any ideas on how to add the polling option . I guess my alternative would be roll back to a more basic webpack config and rebuild that portion of things to use the traditional webpack-dev-server / webpack config but give the above I am not sure that is going to fix it.
I am adding this as a separate answer since it more specifically answers the question in the title, while my other answer more specifically explains what solved my actual problem.
The vue.js webpack template project (which can either be init'd from the Vue CLI or pulled from its repo over here: https://github.com/vuejs-templates/webpack) separates its config files into several different directories.
I am posting this answer so that anyone who runs into the need to add polling to their project will be able to understand how / where to do that.
The base project structure for a Vue.js webpack template project looks like this:
The files that you care about if you are messing with trying to get hot module reload working are related to creating your server primarily with webpack-dev-middleware. The most important files related to that are highlighted here:
Basically if you want to add the polling code to the webpack-dev-middleware server you need to be in the /build/dev-server.js file on lines 20 to 24 that look like this:
var devMiddleware = require('webpack-dev-middleware')(compiler, {
publicPath: webpackConfig.output.publicPath,
quiet: true
})
To add polling you would add it just before or after quiet: true. As a side note, if you are having trouble with HMR I would change "quiet:true" to queit false to get a more verbose read out of whats going on from webpack-dev-middleware. I have included verbose and polling modifications to the above code here:
var devMiddleware = require('webpack-dev-middleware')(compiler, {
publicPath: webpackConfig.output.publicPath,
quiet: false, //Changed to for additional verbosity
watchOptions: { //Add Polling
aggregateTimeout: 300,
poll: 1000
}
})
My other answer is in regards to what ended up solving my problem, not necessarily how to actually add polling (which might be necessary for someone else but did not end up being needed to make my dockerized setup work).
It should also be noted that sometimes when HMR (webpack hot module reload) is not detecting changes it is due to the fact that webpack-hot-middleware or webpack-dev-middleware is running into an issue whereby some invisible characters are / were added to the name of the base project directory (probably by someone building the base Vue project) and therefore webpack on certain OSes is not able to see the changes.
If that happens to you and you are on OSx or running webpack inside of a docker container and you can't get HMR to detect changes, try to rename your vue-webpack project directory and it should work.
Ok. So I can't really take credit for this one since it was actually answered by Discuss user Cristian Pallarés over here: http://webpack.github.io/docs/webpack-dev-server.html#combining-with-an-existing-server
Christian says:
I was just trying the same. I just use "php artisan serve" on localhost:8000, and Webpack Dev Server on localhost:3000. You should make this:
set your webpack config "output.publicPath" as "http://localhost:3000/static/" instead of "/static/"
make your php application load this:
The key is the output.publicPath being absolute. Now, you should run "php artisan serve" and launch your webpack dev server too (in my case I use gulp).
Basically I took that and dug through the Vue.js Webpack Template files to locate the config file where webpack was looking for the public path. the public path setting ended up being in the index.js file located in the /config directory of the template.
I changed my code to look like this:
assetsSubDirectory: 'http://localhost:8080/static/', //!!Changed from /static/
assetsPublicPath: 'http://localhost:8080/', //!!Changed from /
As opposed to the previous setting which DID NOT WORK and looked like this:
assetsSubDirectory: '/static/',
assetsPublicPath: '/',
After that I was able to see my changes hot reload while running the vue.js Webpack template from within my docker container.
Can anyone help me understand how to use BrowserSync with an already running node server?
I know that I have to proxy the server localhost:3000 but where and how would I do that?
Since I'm not using Gulp/Grunt my best guess is proxying a running BrowserSync with express.js but what would that look like?
EDIT:
#RunnyYolk's answer is correct, The best way is to create a script in the package.json file that has BrowserSync proxy your node server. However the issue is more specifically how to use BrowserSync when you need to wait for a process to finish first, such as Angular compilation, then reload your browser.
My build process looks like this:
"build": "del-cli public/js/app && webpack --config webpack.config.dev.js --progress --profile --watch",
How do I call browser-sync reload after that webpack compilation?
I've had browser sync running with a few Node projects. I remember it being a little bit of a fiddle the first couple of times, but definitely worth the effort.
I can't remember exactly what I got caught on, but try these things and let me know if it's still not playing:
Assuming browser-sync is installed, make sure your app.js file (or whatever you've called it) has the server listening on port 3000.
Start the app with a command similar to this:
browser-sync start --proxy localhost:3000 --files="public/stylesheets/*.css", "public/scripts/*.js" "public/views/*.ejs" --no-notify
That works for me. "--files" is a list of files for browser sync to watch, and --no-notify gets rid of some notifications that get fired on each file change - possibly useful in some situations, but I found them annoying.
Looking at this command I notice that there is no reference to node app.js to start up the app. I assume (although I'm not certain) that bowser-sync looks inside package.json for the "start" script. So if my assumption is correct, and if the above command isn't working for you, check that your package.json file has the script included.
I have completed todo app by learning from this video:
Super MEAN Stack Tutorial: Angular, Node/Express, Webpack, MongoDB, SASS, Babel/ES6, Bootstrap
In that video at time 19:18 at this url it is taught that I should use the below two commands in seperate git-bash instances if I want to run it in windows using npm run dev:
node server
webpack-dev-server --progress --colors
But in Linux (or any other OS than windows) you can use this script:
"Scripts": {
"start": "NODE_PATH=$NODE_PATH:./src node server",
"dev": "npm start & webpack-dev-server --progress --colors"
}
So, Is there any way I can do the same in windows?
Also, In that tutorial I can see that port no. 3000 is assigned to node server, but due to using dev dependencies he runs the localhost:8080 in browser. You can see that here. After the tutorial finishes, I followed along and created that app. Now I would like to deploy it. So, I would first like to learn to run test my site in non-dev dependencies mode. i.e. when I type localhost:3000 in browser, my app should run successfully. So, can anybody explain the steps for that?
Update:
I am a newbie in node.js. I watched many videos on node and tried to learn something from that. In all the videos I see that I run node server on port no. 3000 and then I type localhost:3000 in my browser. Now lastly I watched video about mean stack in which he uses webpack. Now, I am confused. I think there are two servers running. first server is webpack's server and second server is node's server. Upto today I typed localhost:3000 in my browser because I mentioned that port 3000 will be used by node in my code. But now in the video he is running localhost:8080 in browser. It means webpack's server is used. Then what happened to node server. Why can't I just run localhost:3000? Also in the video it is explained that webpack is a dev dependency. So, I think after the app is completed and ready to be deployed, my project can be run on the node server (by making some changes to the code, I am not sure). Let's take an example. Now I don't want to deploy the app to a real server. I want the same app to run on my friend's pc. He is not a developer. So, he should not depend on webpack as webpack is a dev dependency. So, he should be able to run the app on node server instead of webpack's server. So, he should type localhost:3000 instead of localhost:8080. That's what I don't understand.
Let's break this down:
If you've defined this script:
"Scripts": {
"start": "NODE_PATH=$NODE_PATH:./src node server",
"dev": "npm start & webpack-dev-server --progress --colors"
}
... then this npm command: npm run dev
... actually invokes these two actions:
a) npm start & # Runs NPM in the background
b) webpack-dev-server --progress --colors # Concurrently runs webpack in the foreground
You can accomplish the same thing in many ways using Windows, starting with a simple .bat file like this:
EXAMPLE: RunDev.bat:
start npm start
webpack-dev-server --progress --colors
=======================================================================
STRONG SUGGESTION:
Please forget about watching videos for a few moments. Try a couple of "hello world" tutorials. More importantly, play with the actual code. Try changing things in the code, and see what happens.
Forget about webpack, at least for the moment.
Think of npm as a "build tool"; not as a way to run your application. At least for a moment.
Focus on "node". Write a "node application".
Part of your "node application" will require "ExpressJS" and "Jade" (now renamed "pug" - I'm still using "Jade"). Use npm to get your ExpressJS and Jade dependencies, but stay focussed on Node.
SUGGESTED TUTORIAL:
A Simple Website in Node.js, Ben Gourley
Be sure to:
a. Download the code
b. Work through the tutorial, using the downloaded code
Please post back (a new post) with any specific questions you might have as you work through the tutorial.