问题
As the title suggests, I'm having trouble remotely accessing my node.js instance hosted on OpenShift. The error I keep getting in my browser's console looks like this:
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
I realize that the headers need to be set to allow cross-domain requests and I've tried several different variations of doing that in my server code.
Currently the server and client code looks like this:
Server:
#!/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();
Client:
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();
   });
});
Any help or pointers are greatly appreciated!
回答1:
It turns out the NodeJS cartridge of my application on OpenShift was faulty. I had to re-create the application completely. After creation I cloned the default project from the git repository OpenShift provides once your application is created. I updated the server.js file to contain the code from "Server" in my question above.
After that, I completed the following steps:
- npm install express --save
- npm install socket.io --save
- git add .
- git commit -m 'update'
- git push
Note:
The "--save" parameter forces an update of your "package.json' which contains the definitions for what modules you are using in your server project. OpenShift uses this to automatically (as far as I can tell) download the required modules on the server-side. In my case, it appears that the express and socket.io got committed after the git push, which means it probably overwrote the server-side modules.
Anyway, I fired up my local website project with the "Client" js above and it works fine. Hope this helps someone else struggling with OpenShift.
来源:https://stackoverflow.com/questions/29889940/access-control-allow-origin-on-openshift-using-node-js-express-and-socket-io