【问题标题】:Securing (ssl) a nodejs/express web service and calling it cross-domain with $.ajax()保护(ssl)nodejs/express web 服务并使用 $.ajax() 跨域调用它
【发布时间】:2012-09-10 17:52:56
【问题描述】:

我已经建立了一个这样的 nodejs 应用程序:

var express =   require('./../../../Library/node_modules/express'); 
var https = require('https');
var app = express();

httpsOptions = {
  key: fs.readFileSync('privatekey.pem'), 
  cert: fs.readFileSync('certificate.pem')  // SELF-SIGNED CERTIFICATE
}

var server = https.createServer(httpsOptions);
app.get('/myservice', function(req, res) {
...
}
server.listen(8443);

我已在我的服务器中为入站请求打开 8443 端口。 在浏览器中,如果我打开 https://mydomain/myservice:8443 我会收到来自浏览器的不受信任的连接警告,这似乎是合乎逻辑的。

然后从我在本地计算机上运行的 test.html(测试跨域问题)中,我执行以下操作:

function testService(){
   var data =  { some JSON };

    $.ajax({
            url: 'https://myserver:8443/myservice',
            dataType: "jsonp",
            data: data,   
            jsonpCallback: "_mycallback",
            cache: false,
            timeout: 5000,
            success: function(data) {
                alert(data);
            },
            error: function(jqXHR, textStatus, errorThrown) {
                alert('Error: ' + textStatus + " " + errorThrown);
            }
        });
}

我的问题是这个请求超时了,我认为它甚至没有到达服务。

  1. 知道为什么吗?

  2. 每当我将此请求发送到服务器时,希望感谢您的友好响应,浏览器警告不受信任的证书会发生什么情况?这会阻止$.ajax() 静默调用服务器并接收响应吗?

【问题讨论】:

    标签: ajax node.js ssl https express


    【解决方案1】:

    您的客户的 JSONP 请求超时的原因几乎可以是任何原因。由于 JSONP 的工作方式,您只能知道请求是失败还是成功,而当它失败时,总是因为超时。也就是说,如果您没有在客户端上保存服务器自签名证书,它几乎肯定会失败。为此,请确保您告诉浏览器始终信任服务器的证书。在 Firefox 中,您还可以转到 Preferences->Encryption->View Certificates->Your Certificates->Import... 将证书添加到 Firefox。其他浏览器应该有类似的界面。

    要解决潜在的跨域问题,请尝试将以下内容添加到您的 app.get('/myservice')

    res.header("Access-Control-Allow-Origin:", "*");
    res.header("Access-Control-Allow-Methods:", "GET");
    

    此外,不同的浏览器处理这些事情的方式也不同。根据我的经验,Firefox 有时比 Chrome 更宽松,但我肯定会在两者中进行测试。

    要测试 HTTPS 问题,首先我会尝试设置一个常规 expressjs 服务器(不加密),而不是在您的请求中使用 https://。如果请求成功,您就知道问题出在 SSL 上。如果是这样,请确保当您的浏览器发出安全警告时,您启用任何允许您将该站点永久添加到您的受信任主机的选项。

    另外,我相信这条线:

    var server = https.createServer(httpsOptions);
    

    应该是:

    var server = https.createServer(httpsOptions, app);
    

    (来自:http://expressjs.com/api.html#app.listen

    您可能还想在var server = https.createServer(httpsOptions);下方添加以下代码进行调试(以便您可以轻松查看您的服务器是否收到请求):

    app.get('*', function(req, res, next) {
        // You *should* also be able to add the response headers here, although I haven't tried.
        console.log('Request received', req, res);
        next();
    })
    

    希望对您有所帮助!

    【讨论】:

    • 对不起,我应该早点回复你的。我实际上改变了我这样做的方式,而不是来自客户端的 JSONP 调用,我现在正在从服务器执行 HTTP 请求。然而,用某种结论来总结这篇文章:迈克,你暗示当使用 JSONP 和 SSL 时,客户端必须始终安装证书?谢谢,再次为迟到表示歉意。
    猜你喜欢
    • 1970-01-01
    • 2017-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-23
    • 2011-01-14
    • 2018-12-25
    • 1970-01-01
    相关资源
    最近更新 更多