【问题标题】:angularjs http request to nodejs apiangularjs http请求到nodejs api
【发布时间】:2017-10-16 02:14:29
【问题描述】:

使用 NodeJs,我设置了一个有效的 API(我可以在浏览器中看到 JSON 结果)。在 Angular 中,我有一个 socket.io 聊天,它通过端口 3030 上的 http 运行。我还在运行一个为 AngularJs 前端提供服务的 apache 服务器(带有 xampp)。

只要我想从 Angularjs 向 Nodejs API 发出请求,我就会在浏览器控制台中收到以下错误

XMLHttpRequest cannot load localhost:3030/api/feed. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.

根据我在谷歌搜索后的理解是,只要我没有在 NodeJS 中运行的 HTTP 服务器,Angular 就无法与 API 通信。 但是我可以在同一个进程中运行socket.io服务器和api的HTTP服务器吗?

server.js

var express = require('express');
var app = express();
var http    = require('http').Server(app);
var io = require('socket.io')(http);

var routes  =   require('./app/api/routes');
app.use('/api', routes);

var chatMembers = {};


io.on('connection', function(socket){

	socket.on("new-message", function(msg){
		console.log(msg);
		var username = msg[username];
		var message = msg[message];
		io.emit("receive-message", msg);
	})

	socket.on("new-connection", function(username){
		chatMembers[socket.id] = username;
		console.log(chatMembers);

		io.emit("online-list", createOnlineList());
	})

	socket.on("disconnect", function(){
		if(chatMembers[socket.id] != undefined){
			console.log(" " + chatMembers[socket.id] + " hat die Verbindung getrennt.");
			delete chatMembers[socket.id];
			io.emit("online-list", createOnlineList());
		}
	})
});


function createOnlineList(){
	//returns list of every member connected to the socket (only name)
  	var onlinelist = [];
	for(var index in chatMembers){
		onlinelist.push(chatMembers[index]);
	}
	return onlinelist;
}


http.listen('3030', function(){
  console.log("Server online");
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
controller.js

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
angular.module('coursemate')
    .controller("chatCtrl", ['$rootScope','$scope', '$http', function($rootScope, $scope, $http){
		var vm = this;
		var socket = window.io('localhost:3030/');
		vm.newMessage = undefined;
		vm.username = undefined;
		vm.messages = [];
		vm.onlinelist = [];
		vm.sendBtnDisabled = true;
		vm.connected = false;


		//socket acions
		socket.on("receive-message", function(msg){
			//socket server send message to us
			$scope.$apply(function(){
			  vm.messages.push(msg);
			});
		});

		socket.on("online-list", function(list){
			//server sends us refreshed list of members
			$scope.$apply(function(){
			  vm.onlinelist = list;
			});
		});

		socket.on('disconnect', function(){
			//connection failed
			vm.connected = false;
			vm.keyEventSendMessage(null);
		});

		socket.on('connect', function(){
			//connection established
			vm.connected = true;
			vm.keyEventSendMessage(null);
		});
		vm.username = undefined;



		vm.sendMessage = function(){
			//we send messsage to socket server
			var newMessage = {
				username: vm.username,
				message: vm.newMessage
			};
			socket.emit("new-message", newMessage);

			var config = {
                headers : {
                    'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
                }
            }
            var data = $.param({
                user: vm.username,
                content: vm.newMessage
            });
			$http.post('app/database/database.php?req=1', data, config).success(function(data) {
	       	});

	        vm.newMessage = undefined;
	        vm.keyEventSendMessage(null);
		};

		vm.createUser = function(username){
			// we "log in" as users
			vm.username = username;
			socket.emit("new-connection", username);
		}
 		vm.keyEventSendMessage = function(event){
 			//fired on keyhit at message input
 			if(typeof(vm.newMessage) != 'undefined' && vm.newMessage != null && vm.newMessage != '' && vm.connected){
 				vm.sendBtnDisabled = false;
 				if(event != null && event.keyCode == 13){
 					vm.sendMessage();
 				}
 			}else{
 				vm.sendBtnDisabled = true;
 			}
 		}

		$http.get('localhost:3030/api/feed').success(function(data) {
			console.log(data);
		});

    }]);

【问题讨论】:

  • 这是浏览器 CORS 策略问题。因为您从一个端口加载 Angular 应用程序,并对另一个端口进行 Ajax 调用,所以浏览器会阻止它。您可以执行以下操作之一:1. 设置 NodeJS 服务器以在基本 url 处为您的 Angular 应用程序提供服务,或者如果不可能,2. 在您的 XAMPP 服务器上配置代理设置以将调用重定向到路径(即 /api/ *) 在localhost:3030 上的 NodeJS 应用程序
  • 第三个选项,只是为了让它工作,但真的不推荐用于您的生产 API,接受所有来源:How to enable cross-origin resource sharing (CORS) in the express.js framework on node.js
  • @JulianSoro 我尝试设置一个 NodeJs 服务器来运行我的 Angularjs,这比预期的要容易。我认为服务器现在也在运行。但是现在我收到一个 AngularJs 错误Uncaught Error: [$injector:modulerr] 并且没有加载任何内容。这是我的app.jscontroller for the view
  • 如果有人使用 Expressjs 和 MongoDB 寻找 Nodejs API 样板。试试这个:github.com/maitraysuthar/rest-api-nodejs-mongodb

标签: angularjs node.js http server


【解决方案1】:

正如上面 Julian Soro 所指出的,这是由于 CORS 政策。

我之前在我的虚拟机上测试并访问主机上的 API 时正在处理这个问题。如果您使用的是 Chrome,那么提及有一个扩展程序来克服这一点可能会有所帮助。您可以下载此扩展程序以在 Chrome 上允许 CORS。 Here 是指向“Allow-Control-Allow-Origin:*”的链接。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2018-04-21
    • 1970-01-01
    • 2014-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-27
    • 2017-08-24
    • 1970-01-01
    相关资源
    最近更新 更多