I'm learning about front-end and back-end interfaces docking. But I met a problem.
My back-end project's port is 8081 and when I send this request http://localhost:8081/hello, I will receive a reponse bodyhello
And my front-end project's port is 8080. When I send request likes http://localhost:8080/hello, the response of it is the same as http://localhost:8081/hello
Here's my vue.config.js
let proxyObj = {};
proxyObj['/']={
ws: false,
target: 'http://localhost:8081',
changeOrigin: true,
pathRewrite: {
'^/': ''
}
}
module.exports= {
devServer: {
host: 'localhost',
port: 8080,
proxy: proxyObj
}
}
If I change proxy: proxyObj to proxy: null then go http://localhost:8080/hello, I receive nothing but a blank. Is anything wrong with my vue.config.js file?
Any help will be appreciated!
DevServer proxy will proxy requests depend on your proxy config:
// '/'means this rule will match all requests
proxyObj['/']={
ws: false,
// target means requests that matched will be sent to http://localhost:8081
target: 'http://localhost:8081',
changeOrigin: true,
pathRewrite: {
'^/': ''
}
}
With this config, all your requests will be sent to the backend server, you will receive a response from the server. If you set your config object to null, your requests will be sent to your frontend project: http://localhost:8080, so you can't receive any response.
See here for more detail about proxy config.
Related
I would like to proxy all requests matching a certain criteria to my backend server. Is there any way to catch all requests and let a subset through the proxy based on things like headers and request paths?
vite.config.ts
server: {
proxy: {
'^.*': {
target: 'https://backend.com',
secure: false,
changeOrigin: true,
ws: true,
configure: proxy => {
// only proxy if request has header "accept: application/json"
// or if it's an image request
}
}
}
}
This seems to catch all requests, but I want my "static" files like index.html, app.js etc. to be served from the devserver, not the proxy.
In vue.js to make Cross-Origin Resource Sharing(CORS) requests, we can configure a proxy rule in the vue.config.js file:
vue.config.js:
module.exports = {
//configure webpack-dev-server behavior
devServer: {
proxy: {
'/api': {
target: 'http://localhost:3000/',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
}
}
Considerations:
My Vue client application run on http://localhost:8080, my api server run on http://localhost:3000.
'/api': { target: 'localhost:3000' ........ }
All requests made to /api' from within my vue application will be forwarded to target: 'localhost:3000'
So if there are requests that start with /api resource path, these requests will be proxied to the target address: localhost:3000
for example:
request localhost:8080/api will be proxied to localhost:3000/api
request localhost:8080/api/1 will be proxied to localhost:3000/api/1 and so on.
pathRewrite: { '^/api': '' }
^/api is a regex.
pathRewrite matches /api path in the target address and replaces it (/api) with empty string
for example, proxied request to localhost:3000/api/1 will become localhost:3000/1
changeOrigin: true enable CORS requests
At the end, With the above proxy rule, every requests starts with /api :(localhost:8080/api, localhost:8080/api/1 ..........) will be proxied to localhost:3000, localhost:3000/1 ........
are my considerations correct??
The official documentation is not very clear.
Thanks
I have a Vue.js project where I have configured a webpack dev-server to proxy all requests to the UI to my backend server. Here is the relevant part of vue.config.js:
devServer: {
contentBase: PATHS.build,
port: 9000,
https: false,
hot: true,
progress: true,
inline: true,
watchContentBase: true,
proxy: {
'^/': {
target: 'http://127.0.0.1:8089',
secure: false
},
}
},
I've noticed that if the HTTP response code from http://127.0.0.1:8089 is anything other than 2xx then the proxy fails with the following error:
Proxy error: Could not proxy request /api/test from localhost:9000 to http://127.0.0.1:8089.
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (HPE_INVALID_CHUNK_SIZE).
This also causes the HTTP response code from the request to localhost:9000 to be 500 for any error and all the information about what went wrong on the server side is lost. This is problematic as I want to be able to extract information from error responses to display to the user.
I know it's possible to do because I had it working on an older Angular project which I think was using Webpack 3 (am now using Webpack 4). I tried copying all the dev-server config from this project but it just doesn't seem to work here!
EDIT: I was wrong. The Proxy error does not occur on every bad response but only for one of the requests which is a multipart file upload. Still unable to reproduce this in a smaller example to put on github though so struggling to pinpoint the cause.
This error message comes from node_modules/#vue/cli-service/lib/util/prepareProxy.js, which define a onError callback for node-http-proxy;
So I did some experiment, make back-end api generate 400 404 500 response, but I didn't got this error.
After I happen to close back-end api, error arise:
Proxy error: Could not proxy request /hello from localhost:8080 to http://localhost:8081 (ECONNREFUSED).
I search in the doc and find these:
The error event is emitted if the request to the target fail. We do not do any error handling of messages passed between client and proxy, and messages passed between proxy and target, so it is recommended that you listen on errors and handle them
So the onError do not handle error code, is called only when request fail (500 response is still treated as a complete request, connection refuse is not)
Go back to your error message, [HPE_INVALID_CHUNK_SIZE] means bad request to the back-end api. In this issue, it gives an solution: add a keep-alive header:
devServer: {
publicPath: 'http://localhost:9090/front/static-dev/build/',
port: 9090,
proxy: {
'/**': {
target: 'http://localhost:8080',
secure: false,
changeOrigin: true,
headers: {
Connection: 'keep-alive'
}
},
open: true
}
I have finally found the problem, and I apologise, it was a lot more of a specific issue than I originally thought when I wrote the question.
Issue was to do with a request which was proxied to another server using the Spring RestTemplate:
e.g.
#PostMapping("/upload")
public ResponseEntity upload(#RequestParam("file") MultipartFile file)
throws Exception {
String baseUrl = serviceProperties.getAddress();
HttpEntity<MultiValueMap<String, Object>> request = createMultipartRequest(file.getBytes());
return restTemplate.postForEntity(baseUrl + "/api/upload", filterRequest, String.class);
}
The ResponseEntity returning from the rest template proxy contained the header "Connection: close" when the response was anything other than 200 which cause the connection to close and caused this request to fail to return anything which subsequently made the dev-server proxy fail on the UI.
Fixed this by not passing the response headers from the rest template proxy to the response:
#PostMapping("/upload")
public ResponseEntity upload(#RequestParam("file") MultipartFile file)
throws Exception {
String baseUrl = serviceProperties.getAddress();
HttpEntity<MultiValueMap<String, Object>> request = createMultipartRequest(file.getBytes());
ResponseEntity response = restTemplate.postForEntity(baseUrl + "/api/upload", filterRequest, String.class);
return new ResponseEntity<>(response.getBody(), response.getStatusCode());
}
Trying to access production REST services using Axios with a Vue-Cli 3.0 dev server (#vue/cli#3.0.0-rc.10, #vue/cli-service-global#3.0.0-rc.10, quasar framework 0.17.5)
My vue.config.js:
module.exports = {
pluginOptions: {
quasar: {
theme: 'ios'
}
},
devServer: {
proxy: 'https://myProduction.server.com'
}
}
I get a 502 bad Gateway error, as listed by Chrome Dev Tool:
Request URL: http://localhost:8080/REST/getText.php
Request Method: POST
Status Code: 502 Bad Gateway
Remote Address: 127.0.0.1:8080
Referrer Policy: no-referrer-when-downgrade
I have tried the more detailed config using route key & changeOrigin: true; to no avail. What am I doing wrong?
I have a Vue.js CLI project working.
It accesses data via AJAX from localhost port 8080 served by Apache.
After I build the project and copy it to a folder served by Apache, it works fine and can access data via AJAX on that server.
However, during development, since the Vue.js CLI website is being served by Node.js which is serving on a different port (8081), I get a cross-site scripting error) and want to avoid cross-site scripting in general.
What is a way that I could emulate the data being provided, e.g. some kind of server script within the Vue.js-CLI project that would serve mock data on port 8081 for the AJAX calls during the development process, and thus avoid all cross-site scripting issues?
Addendum
In my config/index.js file, I added a proxyTable:
dev: {
env: require("./dev.env"),
port: 8081,
autoOpenBrowser: true,
assetsSubDirectory: "static",
assetsPublicPath: "/",
proxyTable: {
"/api": {
target: "http://localhost/data.php",
changeOrigin: true
}
},
And now I make my AJAX call like this:
axios({
method: 'post',
url: '/api',
data: {
smartTaskIdCode: 'activityReport',
yearMonth: '2017-09',
pathRewrite: {
"^/api": ""
}
}
But now I see in my JavaScript console:
Error: Request failed with status code 404
Addendum 2
Apparent axios has a problem with rerouting, so I tried it with vue-resource but this code is showing an error:
var data = {
smartTaskIdCode: 'pageActivityByMonth',
yearMonth: '2017-09'
}
this.$http.post('/api', data).then(response => {
this.pageStatus = 'displaying';
this.activity = response.data['activity'];
console.log(this.activity);
}, response => {
this.pageStatus = 'displaying';
console.log('there was an error');
});
The webpack template has its own documentation, and it has a chapter about API proxying during development:
http://vuejs-templates.github.io/webpack/proxy.html
If you use that, it means that you will request your data from the node server during development (and the node server will proxy< the request to your real backend), and the real backend directly in production, so you will have to use different hostnames in each environment.
For that, you can define an env variable in /config/dev.env.js & /config.prod.env.js