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

6
我有一个简单的Node.js服务器正在运行。这是代码:
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);
});

我可以使用命令行中的curl调用此服务器:

$curl localhost:8090

然而,当我试图从Vue应用程序中调用它时,出现了错误。我有一个运行在localhost:8080的Vue应用程序,并且我想要调用我的localhost:8090服务器。我的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
  }
})

这是 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>

当我点击按钮时,出现以下错误:

XMLHttpRequest无法加载localhost:8090。跨源请求仅支持协议方案:http,data,chrome,chrome-extension,https,chrome-extension-resource。

当我尝试调用另一个服务器,比如google.com时,出现以下错误:

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

因此,似乎Vue将localhost:8080放在调用前面,这可能是我的问题所在?对于我来说,进行服务器调用是完全新的,我只是在使用Vue并在学习Node.js。


请尽量使用完整的地址,例如http://www.google.com或http://localhost:8090。 - Molda
正如 @Molda 所说,您需要在 Google 查询中加上当前的协议方案前缀,否则浏览器会认为您的请求是相对于您当前提供页面的服务器根目录的。 - oligofren
2个回答

6
这与Node或Vue基本无关,而是与浏览器中安全性的实现方式有关。CORS不是一种解决方法。请阅读CORS以了解它为什么是必要的。我的这个问题与你的问题非常相似,回答部分有一些很好的信息。如果要在不使用CORS的情况下调用API,则需要在同一主机、端口和协议上运行,否则将被浏览器阻止。
多年前,在CORS出现之前,您需要使用JSONP来实现相同的功能。当然,您可以查看它以了解其工作原理,但现在我们有了适当的跨域支持,因此几乎没有必要使用该技术。
关于您在“如何在Vue.js中调用API”评论部分的问题,他们会执行以下操作之一:
  1. 在另一个服务器上运行API(例如api.mydomain.com),但在响应中设置CORS标头。
  2. 如上所述,但客户端和服务器使用上面提到的JSONP方法包装响应。
  3. 在与提供页面的服务器相同的服务器上运行API。这意味着api调用将针对诸如localhost:8080/api的端点进行。
  4. 对#3进行改进:只是代理服务器上到达的调用到另一台服务器。这意味着您可以在其他地方运行api服务器,但接受/api调用的主服务器将在剥离/api前缀后将这些请求发送到下一个服务器。通常,人们会在应用程序服务器前设置Apache或Nginx实例,并在其上执行实际代理,但您也可以在应用程序服务器中使用node-proxy等内容进行代理。
您可能已经从中读出了这些信息,但为了节省麻烦(和时间),请直接使用CORS :) @trquoccuong在他的答案中有关于如何使用CORS的详细信息。

1
这非常有帮助! - Arash Saidi

3
跨域问题,您可以使用cors节点模块或添加请求头。如果使用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');

如果使用http模块

res.setHeader

这个错误提示是:"XMLHttpRequest 无法加载 http://localhost:8090/。'Access-Control-Allow-Origin' 标头的值为 'http://localhost:8080/',与提供的来源不相等。因此,源 'http://localhost:8080' 不允许访问。" - Arash Saidi
好的,这个方法能够解决问题,但是我怎样可以在没有绕过的情况下访问服务器?当使用Vue.js时,人们如何调用API? - Arash Saidi
@ArashSaidi 请查看我的答案,其中详细回答了你的问题。 - oligofren

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接