Vue 2 devServer proxying does not work for websocket - vue.js

I have simple web server in python running for example on 127.0.0.1:8080.
I can serve http-requests and web sockets.
This is example of server routes.
...
web.route('*', '/ws', ws_handler),
web.route('*', '/api/some_url', http_handler)
...
And I have frontend part of my application in Vue 2 JS.
I set up vue.config.js file for proxying dev server.
const host = "127.0.0.1"
const port = 8080
devServer: {
proxy: {
"/api": {
target:`http://${host}:${port}/`,
secure:false
},
"/ws": {
target:`ws://${host}:${port}/`,
ws:true,
secure:false,
changeOrigin:true
}
}
}
When I make http requests, for example
let res = await axios.get('/api/some_url');
everything works fine, but if I want to set up websocket connection
soc = new WebSocket('/ws');
I got error
Failed to construct 'WebSocket': The URL '/ws' is invalid.
For websockets my settings does not work.
Connection sets up and everything works fine if full address is provided.
soc = new WebSocket('ws://127.0.0.1:8080/ws');
I have read many articles and had no success for resolve my issue - how can I do proxying websocket connection for Vue JS dev server.

You should instantiate your WebSocket as ws = new WebSocket('ws://' + window.location.host + '/ws');

Related

Cors issue solved by using proxy not working after served in Netlify Create-react-app

I have built a real estate site that makes a an api request to "https://completecriminalchecks.com" In development mode I was getting the dreaded blocked by Cors error. Through some research I found that I needed to use a proxy to solve the issue, which it did in development mode on my local host. But now I have deployed the site to netlify, I am getting a 404 error when making the request. when I look at the request from the network devtools its says
Request URL: https://master--jessehaven.netlify.app/api/json/?apikey=6s4xxxxx13xlvtphrnuge19&search=radius&miles=2&center=98144
I dont think this is right. How do i make netlify make the proper request to the api that was having cors issues in development?
Have you tried netify documentation about it?
Proxy to another service Just like you can rewrite paths like /* to
/index.html, you can also set up rules to let parts of your site proxy
to external services. Let's say you need to communicate from a
single-page app with an API on https://api.example.com that doesn't
support CORS requests. The following rule will let you use /api/ from
your JavaScript client:
/api/* https://api.example.com/:splat 200
Now all requests to /api/... will be proxied through to
https://api.example.com straight from our CDN servers without an
additional connection from the browser. If the API supports standard
HTTP caching mechanisms like ETags or Last-Modified headers, the
responses will even get cached by our CDN nodes.
You do not need to use a proxy, you enable CORRS in your server. Are you using a onde server?
If you use express something like this:
npm install --save cors
And then use it as middleware:
var express = require('express');
var cors = require('cors');
var app = express();
app.use(cors());
Also in your netlify.toml file this will do the trick:
# The following redirect is intended for use with most SPAs that handle
# routing internally.
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
[[headers]]
# Define which paths this specific [[headers]] block will cover.
for = "/*"
[headers.values]
Access-Control-Allow-Origin = "*"
I also faced the same issue and solved by creating a netlify.toml file in root directory.
Here is a sample code for redirect which worked for me.
Place this inside the netlify.toml file.
Documentation guide for proxy :
[[redirects]]
from = "/api/users/tickets/"
to = "https://some-external-site.com/api/users/tickets/"
status = 200
force = true
headers = {Access-Control-Allow-Origin = "*"}
[[redirects]]
from = "/api/users/cars/*"
to = "https://some-external-site.com/api/users/cars/:splat"
status = 200
force = true
headers = {Access-Control-Allow-Origin = "*"}
I also faced the same issue , so I removed the "proxy" from the "package.json" file and created a variable to store the IP addess or URL for backend , then used it with the URL parameter for calling API. The CORS issue is solved in backend by allowing "All origins".
File to store base URL:
constant.js :
export const baseUrl = "https://backEndUrl";
File to call API:
getDataApi.js:
import { baseUrl } from "./constant";
export const getProfileData = () => (dispatch) => {
axios
.get(`${baseUrl }/api/profile`)
.then((res) =>
dispatch({
type: GET_PROFILE,
payload: res.data,
})
)
.catch((err) =>
dispatch({
type: GET_PROFILE,
payload: null,
})
);
};

Why am I getting ERR_CONNECTION_TIMED_OUT in Vue.js?

After creating a new project with vue cli 3 I get this error:
GET http://192.168.1.13:8080/sockjs-node/info?t=1538257166715 net::ERR_CONNECTION_TIMED_OUT sockjs.js?9be2:1605
Operation system: Windows 10
Create vue.config.js with the following code:
module.exports = {
devServer: {
host: 'localhost'
}
};
https://cli.vuejs.org/config/#devserver
To expand on Alexey's answer...
If your frontend app and the backend API server are not running on the same host, you will need to proxy API requests to the API server during development. This is configurable via the devServer.proxy option in vue.config.js. https://cli.vuejs.org/config/#devserver
module.exports = {
devServer: {
proxy: 'http://localhost:8080'
}
}

How to serve data for AJAX calls in a Vue.js-CLI project?

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

Using https on heroku

I'm trying to get my app on heroku to be 'https everywhere'. So far the app is like this:
"use strict";
console.log('working');
//Initial setup
var path, https, privateKey, certificate, port, cdjshelp, util, cookies, oauth, twitter, crypto, _, options, express, auth, lodash, dust, dustjs,
dustjsHelpers, commonDustjsHelpers, app, db, fs, mongoose, mongooseTimes, Comment, Bird, Sighting, Site, User,
Backbone, io;
//node modules, express and dust declarations
path = require('path');
util = require('util');
fs = require('fs');
https = require('https');
privateKey = fs.readFileSync('./config/privatekey.pem').toString();
certificate = fs.readFileSync('./config/certificate.pem').toString();
crypto = require('crypto');
//APP Defn...
app = require('./config/appSetup')(dustjs);
//******** SERVER CONFIG **********//
var port = process.env['PORT'] = process.env.PORT || 4000; // Used by https on localhost
options = {
key: privateKey,
cert: certificate
}
https.createServer(options, app).listen(port, function() {
console.log("Express server listening with https on port %d in %s mode", this.address().port, app.settings.env);
});
I've used the openSSL CLI to generate a privatekey.pem and a certificate.pem and loaded them as options.
I know that heroku has a procedure if you're using DNS records to have the app serve to your own domain. I know that you have to go through the procedure listed here. I'm not remapping any urls or altering any records - my url is birdsapp.heroku.com.
Heroku uses piggyback SSL, so if you setup an http server your app will respond to https requests without any additional config. The problem there is that the http routes are still available, so I've stuck to setting an https server only - but it's timing out with nothing in the logs, so I think that there's a problem with the SSL setup.
Is the above setup correct? Is that the best way to do basic https server on heroku?
OK, it's actually much simpler than that...
You simply create an http server:
//******** SERVER CONFIG **********//
var port = process.env['PORT'] = process.env.PORT || 4000;
http.createServer(app).listen(port, function() {
console.log("Express server listening with http on port %d in %s mode", this.address().port, app.settings.env);
});
and add a route redirect:
app.all('*', function(req, res, next) {
if (req.headers['x-forwarded-proto'] != 'https')
res.redirect('https://' + req.headers.host + req.url)
else
next() /* Continue to other routes if we're not redirecting */
});
heroku takes care of the rest, setting up an http server which is a mirror of your http server and uses their certs, etc.

Node.js proxy for ws.audioscrobbler.com responds with 301 to www.last.fm

I’m trying to use Node.js to set up a proxy to Last.fm’s webservices. The problem is that every request to ws.audioscrobbler.com gets rewritten to www.last.fm. So for example $ curl http://localhost:8000/_api/test123 sends a 301 Moved Permanently to http://www.last.fm/test123.
var express = require('express'),
httpProxy = require('http-proxy');
// proxy server
var lastfmProxy = httpProxy.createServer(80, 'ws.audioscrobbler.com');
// target server
var app = express.createServer();
app.configure(function() {
app.use('/_api', lastfmProxy);
});
app.listen(8000);
At the same time $ curl http://ws.audioscrobbler.com/test123 returns a regular 404 Not Found. I’m not exactly sure what I’m missing here, or if I’m approaching this completely the wrong way.
The reason you get a 301 Moved Permanently is that ws.audioscrobbler.com gets an HTTP request with the hostname "localhost".
One solution is to let the proxy rewrite the hostname to "ws.audioscrobbler.com" before passing it on to the remote server:
var httpProxy = require('http-proxy');
var lastfmProxy = httpProxy.createServer(function (req, res, proxy) {
req.headers.host = 'ws.audioscrobbler.com';
proxy.proxyRequest(req, res, {
host: 'ws.audioscrobbler.com',
port: 80,
});
}).listen(8000);