angularjs http请求到nodejs api

Posted

技术标签:

【中文标题】angularjs http请求到nodejs api【英文标题】:angularjs http request to 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);
		);

    ]);

【问题讨论】:

XMLHttpRequest cannot load https://www.[website].com/的可能重复 这是浏览器 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.js 和controller for the view 如果有人使用 Expressjs 和 MongoDB 寻找 Nodejs API 样板。试试这个:github.com/maitraysuthar/rest-api-nodejs-mongodb 【参考方案1】:

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

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

希望这会有所帮助。

【讨论】:

以上是关于angularjs http请求到nodejs api的主要内容,如果未能解决你的问题,请参考以下文章

向本地nodeJS服务器发出发布请求时出现AngularJS CORS错误

Node.js 使用angularjs取得Nodejs http服务端返回的JSON数组示例

Angularjs + nodejs + 护照跨域请求

AngularJs $http 请求保持挂起,不从数据库返回值

nodeJS,angularJS应用程序中页面请求的服务器身份验证

AngularJS中的$http缓存以及处理多个$http请求