How to configure proxy in Vite? - http-proxy

I was trying to follow the docs and created vite.config.js like this:
const config = {
outDir: '../wwwroot/',
proxy: {
// string shorthand
'/foo': 'http://localhost:4567',
// with options
'/api': {
target: 'http://jsonplaceholder.typicode.com',
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, '')
}
}
};
export default config;
And tried to test it with following calls:
fetch('/foo');
fetch('/api/test/get');
I was expecting to have actual requests as http://localhost:4567/foo and http://jsonplaceholder.typicode.com/test/get
But both of them had my dev server as an origin like this: http://localhost:3000/foo and http://localhost:3000/api/test/get
Did I misunderstand it? How proxies should work?
I also created an issue in the Vite repo but it was closed and I did not understand the closing comment.

Turns out it's needed to specify secure flag to false like this:
proxy: {
'/api': {
target: 'https://localhost:44305',
changeOrigin: true,
secure: false,
ws: true,
}
}
Related github issue

Based on the Vite Config you need to specify it via server -> proxy inside vite.config.js:
export default defineConfig({
server: {
proxy: {
"/api": {
target: "https://your-remote-domain.com",
changeOrigin: true,
secure: false,
},
},
},
// some other configuration
})

For debugging I highly recommend to add event listeners to the proxy, so you can see how the requests are transformed, if they hit the target server, and what is returned.
proxy: {
'/api': {
target: 'https://localhost:44305',
changeOrigin: true,
secure: false,
ws: true,
configure: (proxy, _options) => {
proxy.on('error', (err, _req, _res) => {
console.log('proxy error', err);
});
proxy.on('proxyReq', (proxyReq, req, _res) => {
console.log('Sending Request to the Target:', req.method, req.url);
});
proxy.on('proxyRes', (proxyRes, req, _res) => {
console.log('Received Response from the Target:', proxyRes.statusCode, req.url);
});
},
}
}
proxy will be an instance of 'http-proxy',
Please see for further info https://github.com/http-party/node-http-proxy#options

Related

Get POST request body in Vite server.proxy["/api"].configure

I am migrating a project from Webpack to Vite and have run into an issue with proxying requests to one of the endpoints in the MVC.Net backend.
Due to circumstances of the existing project, I need to handle certain calls manually - such as on initial page load of login page, check whether user is already authenticated and redirect to the main page.
I am trying to figure out how to use server.proxy.configure to handle these requests. I am managing fine with the GET requests, but I cannot seem to receive the POST request's body data.
Here is what I have at the moment:
server: {
proxy: {
"/api": {
target: "https://my.local.environment/",
changeOrigin: true,
configure: (proxy: HttpProxy.Server, options: ProxyOptions) => {
proxy.on("proxyReq", (proxyReq, req, res, options) => {
if (req.method === "GET") {
//handle simple get requests. no problems here
//...
} else {
const buffer = [];
console.log("received post request");
proxyReq.on("data", (chunk) => {
console.log("received chunk");
buffer.push(chunk);
});
proxyReq.on("end", () => {
console.log("post request completed");
const body = Buffer.concat(buffer).toString();
const forwardReq = http.request(
{
host: "https://my.local.environment",
port: 443,
method: "POST",
path: req.url,
headers: {
"Content-Type": "application/json",
"Content-Length": data.length,
},
},
(result) => {
result.on("data", (d) => {
res.write(d);
res.end();
});
}
);
forwardReq.on("error", (error) => {
console.log(error);
});
forwardReq.write(data);
forwardReq.end();
});
}
});
},
secure: false,
},
}
}
The problem is that neither proxyReq.on("data", (chunk) => { nor proxyReq.on("end", (chunk) => { ever actually trigger.
Additionally, req.body is undefined.
I have absolutely no idea where I am supposed to be getting the POST request's body.
I ended up finding a different question about the bypass option and this gave me the solution I was looking for. Ended up only handling the specific GET requests that I need to handle locally instead of forwarding to my deployed environment, and everything else gets handled automatically by vite.
"/api": {
target: "https://my.local.environment/",
changeOrigin: true,
agent: new https.Agent({
keepAlive: true,
}),
bypass(req, res, proxyOptions) {
if (req.method === "GET") {
//... here I get what I need and write to the res object
// and of course call res.end()
}
//all other calls are handled automatically
},
secure: false,
},

error calling Action in store with nuxt-socket.io err_action_access_undefined

I'm having problems calling actions in the store when I configure the nuxt-socket.io in the project, I'm configuring the nuxt-socket.io in the nuxt.config.js and calling the connection in the component according to the nuxt-socket.io documentation ( https://nuxt-socket-io.netlify.app/usage ), but when this configuration is performed, the components can no longer call the actions of the store.
I'm using vuex and vuex-module-decorators.
Config nuxt.config.js:
io: {
sockets: [
{
name: 'home',
url: 'http://url-server-backend.com',
default: true,
}
]
},
Config component:
async beforeMount(){
const token = this.$cookies.get('authToken');
this.socket = this.$nuxtSocket({
name: 'home',
channel: '/socket-io',
persist: true,
teardown: true,
reconnection: false,
extraHeaders: {
Authorization: token
}
});
},
Error:
Image Error action

Strapi v4: How to enable graphql playground in prod?

my-app.herokuapp.com/graphql responses with 'GET query missing.' and doesn't provide graphql playground interface.
Conf from https://docs.strapi.io/developer-docs/latest/plugins/graphql.html#configurations doesn't work for me.
./config/plugins.js
module.exports = ({ env }) => ({
//
graphql: {
config: {
endpoint: "/graphql",
shadowCRUD: true,
playgroundAlways: true,
depthLimit: 100,
apolloServer: {
tracing: false,
},
}
},
});
and this from forums too..
module.exports = ({ env }) => ({
//
graphql: {
endpoint: "/graphql",
shadowCRUD: true,
playgroundAlways: true,
depthLimit: 100,
apolloServer: {
tracing: false,
},
},
});
```
When I tried to query my GraphQL API on Heroku with Postman, at first it said "restricted access" or something like that. Then I realised that, unlike with MongoDB, when you deploy PostgreSQL on Heroku, the latter creates it's own database, different from the one created in dev environment
So, in prod, Strapi content-types are saved, but naturally some things are wiped, like the entries in collections and permissions settings. I had "find" and "findOne" checkboxes unchecked there, so I checked them back on. Prod API still shows "GET query missing", but the data appeared in Postman and the app worked as expected
If you have PostgreSQL deployed, check your Strapi settings (Settings -> Users & Permissions Plugin -> Roles -> Permissions -> name of your collection type) and see if the checkboxes are unchecked and try to check them back. That did the trick for me
This worked for me Strapi v.4 on Heroku with postgreSQL
config/plugins.js
module.exports = ({ env }) => ({
graphql: {
enabled: true,
config: {
endpoint: "/graphql",
shadowCRUD: true,
playgroundAlways: true,
defaultLimit: 10,
maxLimit: 20,
apolloServer: {
tracing: true,
},
},
},
});

Proxy only POST requests (or any other HTTP method) through Webpack Dev Server?

Is there any way to only allow POST requests to be proxied using Webpack Dev Server? My app uses /login for GET requests and unfortunately it is being proxied to my other host regardless of HTTP method.
// Serve the Relay app
const compiler = webpack(config);
appServer = new WebpackDevServer(compiler, {
contentBase: '/public/',
proxy: {
'/login': `http://localhost:${GRAPHQL_PORT}`, // only for POST?
},
publicPath: '/js/',
stats: {
colors: true,
chunks: false,
},
historyApiFallback: true
});
Yes, there is. You can use bypass parameter.
// Serve the Relay app
const compiler = webpack(config);
appServer = new WebpackDevServer(compiler, {
contentBase: '/public/',
proxy: {
'/login': {
target: `http://localhost:${GRAPHQL_PORT}`, // only for POST?
bypass: function(req, res, proxyOptions) {
if(req.method != 'POST') return false;
}
}
},
publicPath: '/js/',
stats: {
colors: true,
chunks: false,
},
historyApiFallback: true
});
documentation Webpack 1
documentation Webpack 2

Webpack-dev-server not sending requests to external domain via proxy

I'm trying to use the webpack-dev-server proxy configuration to send api requests to an external domain and I can't seem to get it working.
Here's my config:
var path = require('path')
module.exports = {
entry: './client/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'public/assets'),
publicPath: 'assets'
},
devServer: {
contentBase: 'public',
proxy:{
'/api/v1*': {
target: 'http://laravelandwebpack.demo/',
secure: false
}
}
}
}
So, anytime my app makes a request with the uri /api/v1... it should send that request to http://laravelandwebpack.demo.
In my Vue app, I'm using the vue-resource to make the requests and I'm defaulting all requests with the needed uri prefix:
var Vue = require('vue')
Vue.use(require('vue-resource'))
new Vue({
el: 'body',
http: {
root: '/api/v1', // prefix all requests with this
headers:{
test: 'testheader'
}
},
ready: function (){
this.$http({
url: 'tasks',
method: 'GET'
}).then(function (response){
console.log(response);
}, function (response){
console.error(response);
})
}
})
The URL's are being constructed correctly, but they're still pointing to localhost:8080 which is the webpack-dev-server:
I read and re-read the docs for webpack-dev-server and I can't figure out where I have it set up wrong. Any ideas?
#Linus Borg is right.
The URL's are being constructed correctly, but they're still pointing to localhost:8080 which is the webpack-dev-server:
This doesn't matter.
In my case, I want to get http://m.kugou.com/?json=true. And I am using #Vue/cli ^3.0.0-beta.15, maybe you need to modify your code according to situation.
So, here is what I did:
App.vue
axios.get('/proxy_api/?json=true').then(data => {
console.log('data', data)
})
vue.config.js
module.exports = {
devServer: {
proxy: {
// proxy all requests whose path starting with /proxy_api to http://m.kugou.com/proxy_api then remove '/proxy_api' string
'/proxy_api': {
target: 'http://m.kugou.com',
pathRewrite: {
'^/proxy_api': '/'
}
}
}
//or just change the origin to http://m.kugou.com
// proxy: 'http://m.kugou.com'
}
}
I use /proxy_api/?json=true then update it to http://m.kugou.com/?json=true by target and pathRewrite.
'/proxy_api' is used to distinguish if the url should be proxied.
Why would I use /proxy_api? Easy to distinguish.
I got the data from http://m.kugou.com/?json=true while the url in the dev-tool is http://localhost:8080/proxy_api/?json=true.
See? that doesn't matter.
I found a workaround solution for that issue. In my case I need to proxy requests to my backend for any /api/* path, so I'm bypassing any requests which does not starts with api.
Sample:
proxy: {
'*': {
target: 'http://localhost:8081',
secure: false,
rewrite: function(req) {
console.log('rewriting');
req.url = req.url.replace(/^\/api/, '');
},
bypass: function(req, res, proxyOptions) {
if (req.url.indexOf('api') !== 0) {
console.log('Skipping proxy for browser request.');
return '/index.html';
}else{
return false;
}
}
}
}

Resources