Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling a Node.js server with Vue.js

I have a simple Node.js server up and running. This is the code:

var http = require('http');
var server = http.createServer();
server.on('request', function(req, res) {
    res.writeHead(200, {
        'content-type': 'text/plain'
    });
    res.write('Hello World!');
    res.end();
})

server.listen(8090);
server.once('listening', function() {
    console.log('Hello World server listening on port %d', 8090);
});

I can call this server using curl from the command line:

$curl localhost:8090

However, when I try to call it from a Vue application, I get an error. I have a Vue application running on localhost:8080, and I want to call my localhost:8090 server. My main.js Vue file is this:

import Vue from 'vue'
import resources from 'vue-resource'
Vue.use(resources)

import App from './components/App.vue'

import style from './styles/main.scss'

/**
 * Root Vue instance
 * @param {[element]} el: 'body' [Adds to the html body]
 * @param {[component]} components: {app: App} [Renders ./component/App]
 */
new Vue({
  el: 'body',
  components: {
    app: App
  }
})

And this is the App component:

<template>

<h1>{{ msg }}</h1>

<input v-model="msg">
<button v-on:click="get">Call Server</button>

</template>

<script>

export default {
    data: function() {
        return {
            msg: 'Hello World!'
        }
    },
    methods: {
        get: function() {
            // GET request
            this.$http({
                url: 'localhost:8090',
                method: 'GET'
            }).then(function(response) {
                console.log('ok');
            }, function(response) {
                console.log('failed');
            });
        }
    }
}

</script>

When I click the button I get this error:

XMLHttpRequest cannot load localhost:8090. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.

When I try to call another server, like google.com, I get this error:

build.js:19188 GET http://localhost:8080/google.com 404 (Not Found)

So it seems like Vue is putting the localhost:8080 in front of the call, and maybe this is where my problem lies? Making server calls is completely new to me, I'm just playing around with Vue and want to learn Node.js while I do so.

like image 788
Arash Saidi Avatar asked Apr 22 '16 11:04

Arash Saidi


People also ask

How do I connect to node JS and Vue JS?

json resides and configures the appropriate API paths. With this in place, all the calls start with /api will be redirected to http://localhost:3080 where the nodejs API running. Once this is configured, you can run the Vue app on port 8080 and nodejs API on 3080 still make them work together.

Does Vue work with node js?

To install and use the Vue CLI as well as run the Vue application server, you'll need the Node. js JavaScript runtime and npm (the Node. js package manager) installed. npm is included with Node.

Can Vue be used as a server?

And the answer is: Yes, absolutely! Vue doesn't care about your backend and your server-side language, it's a client-side framework, it runs in the browser! It also doesn't matter if you drop your Vue import into the (server-rendered) HTML files or if you're building a SPA.


1 Answers

This basically has nothing to do with Node or Vue and everything to do with how security in the browser is implemented. CORS is not a workaround. Read up on CORS to see why it is needed. This question of mine, which is quite similar to yours, has some good info in the answers sections as well. To be able to call an API without using CORS it needs to run on the same host, port and protocol, otherwise it will be blocked by your browser.

Years ago, before the advent of CORS, you needed to use JSONP to achieve the same. You can of course have a look at it to see how this works, but nowadays there is very little need for that technique as we have proper cross-domain support in the form of CORS.

Regarding your question in one of the comment sections on "How do people call API's when working with Vue.js?", they do one of the following:

  1. Run the API on another server (such as api.mydomain.com), but set the CORS headers on the response.
  2. As above, but the client and server wraps responses using the JSONP method mentioned above.
  3. Run the API on the same server as the one serving pages. This means api calls will be done against an endpoint such as localhost:8080/api
  4. Twist on #3: just proxy calls coming in on the server to another server. Meaning you can have your api server running elsewhere, but your main server that is accepting calls on /api will just send these requests on the the next server after stripping off the /api prefix. Usually, people either setup an Apache or Nginx instance in front of your app server and do the actual proxying on that, but you can also do it in your app server, using something like node-proxy.

You can probably read this through the lines already, but save yourself some trouble (and time) and just use CORS :) @trquoccuong has the details on doing this in his answer.

like image 160
oligofren Avatar answered Oct 27 '22 00:10

oligofren