With NodeJs I have set up an API which works (I can see the JSON result in my Browser). In Angular I have a socket.io chat which runs via http on port 3030. I am also running an apache server (with xampp) which serves the AngularJs frontend.
As soon as I want to make a request from Angularjs to the Nodejs API I get the following error in the browsers console
XMLHttpRequest cannot load localhost:3030/api/feed. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
From what I understood after googling is that Angular can't communicate with the API as long as I dont have an HTTP server running in NodeJS. But can I run the socket.io server and the HTTP server for the api in the same process?
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);
});
}]);
1 Answer 1
This is due to CORS policy, as Julian Soro pointed above.
I was dealing with this problem before when testing on my virtual machine and access the API on the host. If you are using Chrome, probably it could be helpful to mention there is an extension to overcome that. You could download this extension to allow CORS on Chrome. Here is the link to 'Allow-Control-Allow-Origin:*'.
Hope this could help.
localhost:3030Uncaught Error: [$injector:modulerr]and nothing is loaded. This is my app.js and the controller for the view