简体   繁体   English

使用Vue.js调用Node.js服务器

[英]Calling a Node.js server with Vue.js

I have a simple Node.js server up and running. 我有一个简单的Node.js服务器启动并运行。 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来调用此服务器:

$curl localhost:8090

However, when I try to call it from a Vue application, I get an error. 但是,当我尝试从Vue应用程序调用它时,我收到错误。 I have a Vue application running on localhost:8080, and I want to call my localhost:8090 server. 我有一个在localhost:8080上运行的Vue应用程序,我想调用我的localhost:8090服务器。 My main.js Vue file is this: 我的main.js Vue文件是这样的:

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: 这是App组件:

<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. XMLHttpRequest无法加载localhost:8090。 Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource. 交叉源请求仅支持协议方案:http,data,chrome,chrome-extension,https,chrome-extension-resource。

When I try to call another server, like google.com, I get this error: 当我尝试拨打另一台服务器时,例如google.com,我收到此错误:

build.js:19188 GET http://localhost:8080/google.com 404 (Not Found) build.js:19188获取http:// localhost:8080 / google.com 404(未找到)

So it seems like Vue is putting the localhost:8080 in front of the call, and maybe this is where my problem lies? 所以看起来Vue正在把localhost:8080放在电话前面,也许这就是我的问题所在? 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. 进行服务器调用对我来说是全新的,我只是在玩Vue并希望在我这样做时学习Node.js。

This basically has nothing to do with Node or Vue and everything to do with how security in the browser is implemented. 这基本上与Node或Vue无关,而且与浏览器的安全性如何实现有关。 CORS is not a workaround. CORS不是一种解决方法。 Read up on CORS to see why it is needed . 阅读CORS以了解它的原因 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. 为了能够在不使用CORS的情况下调用API,它需要在相同的主机,端口和协议上运行,否则它将被您的浏览器阻止。

Years ago, before the advent of CORS, you needed to use JSONP to achieve the same. 多年前,在CORS出现之前,你需要使用JSONP来实现同样的目标。 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. 您当然可以查看它是如何工作的,但是现在很少需要这种技术,因为我们以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: 关于您在“使用Vue.js时人们如何调用API?”的评论部分中的问题,他们会执行以下操作之一:

  1. Run the API on another server (such as api.mydomain.com ), but set the CORS headers on the response. 在另一台服务器(例如api.mydomain.com )上运行API,但在响应上设置CORS标头。
  2. As above, but the client and server wraps responses using the JSONP method mentioned above. 如上所述,但客户端和服务器使用上面提到的JSONP方法包装响应。
  3. Run the API on the same server as the one serving pages. 在与服务页面相同的服务器上运行API。 This means api calls will be done against an endpoint such as localhost:8080/api 这意味着api调用将针对端点进行,例如localhost:8080/api
  4. Twist on #3: just proxy calls coming in on the server to another server. 扭转#3:只是将服务器上的代理呼叫转移到另一台服务器。 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. 这意味着您可以让api服务器在其他地方运行,但是接受/api上的呼叫的主服务器将在剥离/api前缀后在下一个服务器上发送这些请求。 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 . 通常,人们要么在应用服务器前面设置一个Apache或Nginx实例,并在其上进行实际代理,但你也可以在app服务器中使用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. 你可能已经通过这些行阅读了这个,但是省去了一些麻烦(和时间)并且只使用CORS :) @trquoccuong在他的回答中有详细说明。

CORS problems, you can use cors node module or add request header CORS问题,您可以使用cors节点模块或添加请求标头

if use Express 如果使用快递

res.header('Access-Control-Allow-Origin', 'http://localhost:8080');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');

if use http module 如果使用http模块

res.setHeader

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM