I am working on a web app using vue.js as a UI and node.js as server. Vue is running on port 8080 and Node.js is running on 3001, so to to make API calls I am using a proxy which is not working as expected.
The below code in my vue.config.js is used for the proxy:
module.exports = {
devServer: {
proxy: {
'^/api': {
target: 'http://localhost:3001',
ws: true,
secure: false
}
}
}
}
And below is my Home page file which will call the URL using axios
import axios from 'axios'
export default {
data () {
return {
categories: []
}
},
created () {
axios.get('/api/v1/categories')
.then(res => {
debugger
this.categories = res.data
})
}
}
As I am a new to vue.js, I don't know what is going wrong.
EDIT
This is the error I am getting:
Proxy error: Could not proxy request /api/v1/categories from localhost:8080 to http://localhost:3001/.
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNRESET).
I encountered this problem, solved it by replacing localhost with 127.0.0.1, then with [::1]
A few months later, i had to go back to 127.0.0.1…
Maybe did some process change my hosts file.
You should type ping localhost in your terminal in order to check your current configuration and use the result to set your proxy.
Try this
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://localhost:3001',
ws: true,
secure: false
}
}
}
}
Also, check whether you have set a base path for axios. If so, please remove api from the axios call since base path will also get added to the axios call.
Related
I'm working on a website made with React, run with npm. The website currently uses a JS API run with the website code, but we're migrating to using an external REST API. Everything's configured correctly to run locally with a webpack dev server:
proxy: {
'/apiv1': 'http://localhost:5000/', // in prod, run in the same container
'/api': {
target: 'http://localhost:8080/', // in prod, run separately on a different url (api.website.com)
pathRewrite: { '^/api/': '' },
},
},
In the console, I see errors complaining that some data is undefined (using the minified variable names, so difficult to track down--but almost certainly data from the API).
I checked if it was a CORS issue per this question, but I'm still having the same issue with CORS disabled completely.
I can successfully ping the api with a direct request, placed at the beginning of the base App's render method:
axios.get("https://api.website.com/")
I've tried to add the following to my package.json per this:
"homepage": ".",
"proxy": {
"/api": {
"target": "https://api.website.com",
"pathRewrite": {
"^/api": ""
},
"changeOrigin": true
}
},
In general -- how can I proxy requests for website.com/api/request to api.website.com/request in production? Is there something else I'm configuring incorrectly?
Please let me know if there's any more information I can add!
Edit:
I've also tried configuring the proxy with http-proxy-middleware:
// src/setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function (app) {
app.use(
'/api',
createProxyMiddleware({
target: "https://api.website.com",
pathRewrite: {
"^/api": ""
},
changeOrigin: true,
})
);
};
Proxying api requests in production for React/Express app
In production we can't use (proxy).. instead we can set a variable in the frontend for the backend URL, and vise versa.
https://github.com/facebook/create-react-app/issues/1087#issuecomment-262611096
proxy is just that: a development feature. It is not meant for production.
These suggest that it's entirely impossible. Makes sense that the proxy option won't work, but I can't say I understand why there's no equivalent functionality for a production environment. It seems the best option for me is making all calls to the full domain instead of proxying.
If you're using nginx, the linked answers suggest using that to proxy the requests:
upstream backend-server {
server api.example.com;
}
server {
listen 80;
server_name example.com;
root /var/www/build;
index index.html;
location /api/ {
proxy_pass http://backend-server;
}
location / {
try_files $uri /index.html;
}
}
After switch to vite, I am trying to mimic proxy: "http://localhost:5000" which I previously used in package.json
Here is my vite config
export default defineConfig({
plugins: [react()],
server: {
proxy: {
"/api": {
target: "http://localhost:5000",
changeOrigin: true,
secure: false,
},
},
},
});
I have react app running on port 3000. When I send a request in the root url (http://localhost:3000) everything works fine
const { data } = await axios.get("api/user/me");
Well, not really fine. Even though proper data is returned in response, in the console request gets sent to http://localhost:3000/api/user/me instead of http://localhost:5000/api/user/me. Can anyone explain this behaviour?
The main problem is that when I navigate to another page (e.g. http://localhost:3000/dashboard), then the same request gets sent to http://localhost:3000/dashboard/api/user/me.
What am I doing wrong? I want to send requests to http://localhost:5000, no matter the location
I found a workaround by specifying FE url before every request const { data } = await axios.get("http://localhost:3000/api/user/me");, but still is there a way to mimic package.json proxy behaviour?
I resolved the issue by changing axios defaults
axios.defaults.baseURL = `http://localhost:5000`
By doing this I achieved what I was going for. Requests get sent to the proper endpoint no matter the location
I solved this problem by using Axios.
Create a new file. I called mine emailApi.
Setup your axios, like so:
export const emailApi = axios.create({baseURL: "http://localhost:<yourPortNumber>"})
Done! Whenever you want to send a request to your server, import the emailApi and you're good.
Also in your server, make sure to install cors and set it as a middleware, like so:
express().use(cors({origin: <viteLocalServer>}))
we are running our Java app (spring based) including the UI modules in a Tomcat container. Calling tomcat directly over http://localhost:8080 a login page is displayed and a redirect 302 occurs to the web app.
Now we want to develop the UI modules separately from the Java app by running an Express server with http-middleware-proxy and browser-sync. The modules have not been extracted out of the war-file and are running on the Tomcat instance. For testing purposes we just copied the UI module to another dir to setup Express and corresponding modules.
The problem is that we are not able to get the authorization cookies (JSESSIONID) and CSRF tokens correctly set.
How can the redirect 302 intercepted and redirected to the separately hosted UI app?
We´ve got the authorization working, so no login is required but calling the "copied app" does not work and results in "auth error" or "forbidden".
We already checked the documentation and other posts in here.
var cookie;
function relayRequestHeaders(proxyReq, req) {
if (cookie) {
proxyReq.setHeader('cookie', cookie);
}
};
function relayResponseHeaders(proxyRes, req, res) {
var proxyCookie = proxyRes.headers["set-cookie"];
if (proxyCookie) {
cookie = proxyCookie;
}
};
const oOptions = {
target: 'http://localhost:8080',
changeOrigin: true,
auth: 'user:pw',
pathRewrite: {
'^/dispatcher': '/dispatcher',
},
//cookieDomainRewrite: 'localhost',
onProxyReq: relayRequestHeaders,
onProxyRes: relayResponseHeaders,
logLevel: 'debug'
};
const wildcardProxy = createProxyMiddleware( oOptions );
app.use(wildcardProxy);
Any ideas on how to get that solved?
Thanks.
Update:
We tried as well to filter context paths which works but then it does not access the resources of the hosted webapp via express.
const oOptions = {
target: 'http://localhost:8080',
changeOrigin: true,
auth: 'user:pw',
logLevel: 'debug'
};
const wildcardProxy = createProxyMiddleware(['index.html', 'index.jsp', '!/resources/scripts/**/*.js'], oOptions );
app.use(wildcardProxy);
This is because we are proxying "/". How can it be achieved to only proxy the login and initial index.jsp but then using the resources of "webapp" and not of tomcat resources (e.g. *.js)? Is this possible somehow via the app.use to bind to certain files and paths?
We got that solved. We just excluded certain files from being served by the target host.
config.json:
{
...
"ignoreFilesProxy": ["!/**/*.js", "!/**/*.css", "!/**/*.xml", "!/**/*.properties"],
...
}
...
createProxyMiddleware(config.ignoreFilesProxy, oOptions);
...
Next step was to change the Maven build, so that the UI modules are not served/packaged with the war-file in the local dev environment. We solved that by introducing two Maven Profiles to include or exclude the UI modules in the WAR-project.
I'm setting up a Vue app with Koa as the backend. I've implemented a simple login system, using koa-session for sessions. This is all fine when I access the server directly (actually navigating to my server port and performing a request), but when I use fetch to access the data from my front end port, it does not recall each fetch as the same session and creates a new session each time. This is problematic because it doesn't detect the user as being logged in. What ends up happening is that a new session key is created each time I access the API, even without refreshing the page.
Here is my Koa-session config file:
import Koa from "koa";
import session from "koa-session";
import { getCookie } from "../actions/getCookie";
import { setCookie } from "../actions/setCookie";
import { destroyCookie } from "../actions/destroyCookie";
export const config: Readonly<Partial<session.opts>> = {
store: {
get: getCookie,
set: setCookie,
destroy: destroyCookie
},
key: "api:sess",
maxAge: 86400000,
httpOnly: true,
renew: true,
signed: false
};
export const useSession = (app: Koa) => session(config, app);```
Turns out it was with my fetch. I had credentials: "same-origin" instead of credentials: "include" and it messed everything up.
If I have project in vue-cli with no node.js (or express.js), can I somehow unblocke this CORS access?
I tried to add a code in vue.config.js
vue.config.js:
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://18.700.121.3:8000/',
ws: true,
changeOrigin: true
}
}
}
}
vue template
import axios from 'axios'
export default {
name: "Jokes",
data () {
return {
songs: null,
}
},
},
mounted () {
const config = {headers: {'Access-Control-Allow-Origin': '*'}};
axios
.get(`http://2.788.121.2:4000/`, config) //it a sample api
.then(
response => (
this.songs= response.data))
}
}
</script>
but it didn't help. Also I tried to swich-on chrome plugin Access-Control-Allow-Origin, where I add access to localhost:8080, but still doesnt work.
So it is possible, that only option is install node.js and add res.header("Access-Control-Allow-Headers","*");
Try remove the header const config = {headers: {'Access-Control-Allow-Origin': '*'}}; from the request
The additional header will just confuse the browser
First way,
Use Cors Plugin in chrome Eg- Moseif CORS or Degrade your chrome version less than 71.
Second way, If you can modify the server-side code (If using express)
Add below codes, You can easily solved this problem.
var cors = require('cors')
var app = express()
app.use(cors())
Close the Chrome.
Hold down the Windows Key and Press R on your keyboard. The "RUN" dialog box will open.
Insert the following input field chrome --disable-web-security --user-data-dir and run it
Now run your vue.js app
Hope it helps.