Access-Control-Allow-Origin 在 OpenShift 上使用 Node.js、express 和 socket.io
Access-Control-Allow-Origin on OpenShift using Node.js, express, and socket.io
如标题所示,我无法远程访问托管在 OpenShift 上的 node.js 实例。我在浏览器控制台中不断收到的错误如下所示:
XMLHttpRequest cannot load http://app-domain.rhcloud.com:8000/socket.io/?EIO=3&transport=polling&t=1430117973290-2. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8383' is therefore not allowed access. The response had HTTP status code 503. (08:59:33:579 | error, javascript)
at public_html/index.html
我意识到 headers 需要设置为允许 cross-domain 请求,我已经在我的服务器代码中尝试了几种不同的做法。
目前服务器和客户端代码如下所示:
服务器:
#!/bin/env node
var test = {
init: function() {
test.protocol = require('http');
test.express = require('express');
test.fs = require('fs');
test.socket = require('socket.io');
test.key();
test.setup();
test.cache();
test.handlers();
test.server();
test.start();
},
key: function() {
test.cache_get = function(key) { return test.zcache[key]; };
},
setup: function() {
test.ipaddress = process.env.OPENSHIFT_NODEJS_IP || '127.0.0.1';
test.port = process.env.OPENSHIFT_NODEJS_PORT || 8080;
},
cache: function() {
if (typeof test.zcache === 'undefined') {
test.zcache = { 'index.html': '' };
}
test.zcache['index.html'] = test.fs.readFileSync('./index.html');
},
handlers: function() {
process.on('exit', function() { test.terminator(); });
['SIGHUP', 'SIGINT', 'SIGQUIT', 'SIGILL', 'SIGTRAP', 'SIGABRT', 'SIGBUS', 'SIGFPE', 'SIGUSR1', 'SIGSEGV', 'SIGUSR2', 'SIGTERM'].forEach(function(element, index, array) {
process.on(element, function() { test.terminator(element); });
});
},
terminator: function() {
if (typeof sig === 'string') {
console.log('%s: Received %s - terminating sample app ...', Date(Date.now()), sig);
process.exit(1);
}
console.log('%s: Node server stopped.', Date(Date.now()));
},
route: function() {
test.routes = { };
test.routes['/asciimo'] = function(req, res) {
var link = 'http://i.imgur.com/kmbjB.png';
res.send('<html><body><img src="' + link + '"></body></html>');
};
test.routes['/'] = function(req, res) {
res.setHeader('Content-Type', 'text/html');
res.send(test.cache_get('index.html') );
};
},
server: function() {
test.route();
test.app = test.express();
test.app.configure(function() {
test.app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
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 ('OPTIONS' === req.method) {
res.send(200);
}
else {
next();
};
});
});
test.http = test.protocol.Server(test.app);
test.io = test.socket(test.http);
test.io.set('origins', '*:*');
for (var r in test.routes) {
test.app.get(r, test.routes[r]);
}
},
start: function() {
test.http.listen(test.port, test.ipaddress, function() {
test.io.sockets.on('connection', function (socket) {
test.config.listen(socket);
});
console.log('%s: Node server started on %s:%d ...', Date(Date.now() ), test.ipaddress, test.port);
});
test.app.get('/', function (req, res) {
res.sendfile('index.html');
});
},
config: {
listen: function(socket) {
socket.on('test', function(data) {
socket.emit('news', data);
});
}
}
};
test.init();
客户:
var test = {
socket: null,
init: function() {
try {
//test.socket = io('ws://127.0.0.1:8080');
test.socket = io.connect('ws://app-domain.rhcloud.com:8000');
test.events();
}
catch (e) {
alert(e.message);
}
},
events: function() {
test.socket.on('news', function (data) {
alert(JSON.stringify(data, null, 4));
});
},
send: function() {
try {
test.socket.emit('test', { test: 'data' });
}
catch (e) {
alert(e.message);
}
}
};
test.init();
$(document).ready(function() {
$('#test').click(function() {
test.send();
});
});
非常感谢任何帮助或指点!
事实证明,我在 OpenShift 上的应用程序的 NodeJS 插件有问题。我不得不完全重新创建应用程序。创建后,我从 OpenShift 在创建应用程序后提供的 git 存储库中克隆了默认项目。我更新了 server.js 文件以包含上面问题中“Server”的代码。
之后,我完成了以下步骤:
- npm install express --save
- npm 安装socket.io --保存
- git 添加 .
- git commit -m 'update'
- git推
注:
“--save”参数强制更新您的“package.json”,其中包含您在服务器项目中使用的模块的定义。OpenShift 自动使用它(据我所知)告诉)在服务器端下载所需的模块。在我的例子中,快递和 socket.io 似乎在 git 推送后得到提交,这意味着它可能覆盖了服务器端模块。
无论如何,我用上面的“Client”js启动了我的本地网站项目,它工作正常。希望这可以帮助其他在 OpenShift 上苦苦挣扎的人。
如标题所示,我无法远程访问托管在 OpenShift 上的 node.js 实例。我在浏览器控制台中不断收到的错误如下所示:
XMLHttpRequest cannot load http://app-domain.rhcloud.com:8000/socket.io/?EIO=3&transport=polling&t=1430117973290-2. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8383' is therefore not allowed access. The response had HTTP status code 503. (08:59:33:579 | error, javascript) at public_html/index.html
我意识到 headers 需要设置为允许 cross-domain 请求,我已经在我的服务器代码中尝试了几种不同的做法。
目前服务器和客户端代码如下所示:
服务器:
#!/bin/env node
var test = {
init: function() {
test.protocol = require('http');
test.express = require('express');
test.fs = require('fs');
test.socket = require('socket.io');
test.key();
test.setup();
test.cache();
test.handlers();
test.server();
test.start();
},
key: function() {
test.cache_get = function(key) { return test.zcache[key]; };
},
setup: function() {
test.ipaddress = process.env.OPENSHIFT_NODEJS_IP || '127.0.0.1';
test.port = process.env.OPENSHIFT_NODEJS_PORT || 8080;
},
cache: function() {
if (typeof test.zcache === 'undefined') {
test.zcache = { 'index.html': '' };
}
test.zcache['index.html'] = test.fs.readFileSync('./index.html');
},
handlers: function() {
process.on('exit', function() { test.terminator(); });
['SIGHUP', 'SIGINT', 'SIGQUIT', 'SIGILL', 'SIGTRAP', 'SIGABRT', 'SIGBUS', 'SIGFPE', 'SIGUSR1', 'SIGSEGV', 'SIGUSR2', 'SIGTERM'].forEach(function(element, index, array) {
process.on(element, function() { test.terminator(element); });
});
},
terminator: function() {
if (typeof sig === 'string') {
console.log('%s: Received %s - terminating sample app ...', Date(Date.now()), sig);
process.exit(1);
}
console.log('%s: Node server stopped.', Date(Date.now()));
},
route: function() {
test.routes = { };
test.routes['/asciimo'] = function(req, res) {
var link = 'http://i.imgur.com/kmbjB.png';
res.send('<html><body><img src="' + link + '"></body></html>');
};
test.routes['/'] = function(req, res) {
res.setHeader('Content-Type', 'text/html');
res.send(test.cache_get('index.html') );
};
},
server: function() {
test.route();
test.app = test.express();
test.app.configure(function() {
test.app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
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 ('OPTIONS' === req.method) {
res.send(200);
}
else {
next();
};
});
});
test.http = test.protocol.Server(test.app);
test.io = test.socket(test.http);
test.io.set('origins', '*:*');
for (var r in test.routes) {
test.app.get(r, test.routes[r]);
}
},
start: function() {
test.http.listen(test.port, test.ipaddress, function() {
test.io.sockets.on('connection', function (socket) {
test.config.listen(socket);
});
console.log('%s: Node server started on %s:%d ...', Date(Date.now() ), test.ipaddress, test.port);
});
test.app.get('/', function (req, res) {
res.sendfile('index.html');
});
},
config: {
listen: function(socket) {
socket.on('test', function(data) {
socket.emit('news', data);
});
}
}
};
test.init();
客户:
var test = {
socket: null,
init: function() {
try {
//test.socket = io('ws://127.0.0.1:8080');
test.socket = io.connect('ws://app-domain.rhcloud.com:8000');
test.events();
}
catch (e) {
alert(e.message);
}
},
events: function() {
test.socket.on('news', function (data) {
alert(JSON.stringify(data, null, 4));
});
},
send: function() {
try {
test.socket.emit('test', { test: 'data' });
}
catch (e) {
alert(e.message);
}
}
};
test.init();
$(document).ready(function() {
$('#test').click(function() {
test.send();
});
});
非常感谢任何帮助或指点!
事实证明,我在 OpenShift 上的应用程序的 NodeJS 插件有问题。我不得不完全重新创建应用程序。创建后,我从 OpenShift 在创建应用程序后提供的 git 存储库中克隆了默认项目。我更新了 server.js 文件以包含上面问题中“Server”的代码。
之后,我完成了以下步骤:
- npm install express --save
- npm 安装socket.io --保存
- git 添加 .
- git commit -m 'update'
- git推
注:
“--save”参数强制更新您的“package.json”,其中包含您在服务器项目中使用的模块的定义。OpenShift 自动使用它(据我所知)告诉)在服务器端下载所需的模块。在我的例子中,快递和 socket.io 似乎在 git 推送后得到提交,这意味着它可能覆盖了服务器端模块。
无论如何,我用上面的“Client”js启动了我的本地网站项目,它工作正常。希望这可以帮助其他在 OpenShift 上苦苦挣扎的人。