Nginx 服务器同时具有 HTTP 和 HTTPS,浏览器选择 HTTP

Nginx server with both HTTP and HTTPS, browser selecting HTTP

我正在 Nginx 服务器上部署 Web。 Nginx配置了http和https两种版本,像这样:

upstream stream {
    server unix:///home/project/project.sock;
}

server {
    listen 443;

    ssl on;
    ssl_certificate certificate.crt;
    ssl_certificate_key server.key;

    server_name server.com;
    server_name *.server.com;
    client_max_body_size 0;
    charset utf-8;

    # Main
    location / {
        uwsgi_pass stream;

        # Parametros de uWSGI
        uwsgi_param  QUERY_STRING       $query_string;
        uwsgi_param  REQUEST_METHOD     $request_method;
        uwsgi_param  CONTENT_TYPE       $content_type;
        uwsgi_param  CONTENT_LENGTH     $content_length;

        uwsgi_param  REQUEST_URI        $request_uri;
        uwsgi_param  PATH_INFO                      $document_uri;
        uwsgi_param  DOCUMENT_ROOT      $document_root;
        uwsgi_param  SERVER_PROTOCOL    $server_protocol;

        uwsgi_param  REMOTE_ADDR        $remote_addr;
        uwsgi_param  REMOTE_PORT        $remote_port;
        uwsgi_param  SERVER_ADDR        $server_addr;
        uwsgi_param  SERVER_PORT        $server_port;
        uwsgi_param  SERVER_NAME        $server_name;

        uwsgi_param UWSGI_SCHEME    https;
    }
}

server {
    listen 80;
    server_name server.com;
    server_name *.server.com;
    client_max_body_size 0;
    charset utf-8;

    # Main
    location / {
        uwsgi_pass  stream;

        # Parametros de uWSGI
        uwsgi_param  QUERY_STRING       $query_string;
        uwsgi_param  REQUEST_METHOD     $request_method;
        uwsgi_param  CONTENT_TYPE       $content_type;
        uwsgi_param  CONTENT_LENGTH     $content_length;

        uwsgi_param  REQUEST_URI        $request_uri;
        uwsgi_param  PATH_INFO                      $document_uri;
        uwsgi_param  DOCUMENT_ROOT      $document_root;
        uwsgi_param  SERVER_PROTOCOL    $server_protocol;

        uwsgi_param  REMOTE_ADDR        $remote_addr;
        uwsgi_param  REMOTE_PORT        $remote_port;
        uwsgi_param  SERVER_ADDR        $server_addr;
        uwsgi_param  SERVER_PORT        $server_port;
        uwsgi_param  SERVER_NAME        $server_name;

        uwsgi_param UWSGI_SCHEME    http;
    }
}

一切正常,但当您键入 server.com 时,浏览器总是 select 使用 HTTP 版本,我希望它默认为 select HTTPS 版本。

我该怎么做?

如果您只想通过 HTTPS 提供服务,则需要重定向 HTTP 服务器块中的所有 HTTP 请求:

server {
    listen 80;
    server_name example.com *.example.com;
    return 301 https://$server_name$request_uri;
}

然后您可以删除 HTTP 服务器中的所有其他配置,因为它们永远不会被使用。

您无法控制浏览器的功能(不幸的是);默认情况下,如果用户未键入 方案 (这是 URL 的 http:// 部分的技术名称);那么浏览器将默认为 http.

如果您只想通过 https:// 为站点提供服务,则必须将所有请求重定向到 https:// 版本。

这里你必须小心,如果你按照 的建议实施盲目重定向,任何 POST 请求都将失败并且无法正确重定向。

一种更兼容的重定向方法是检查请求的类型:

server {
    listen   80;
    server_name example.com;

    location / {
      if ($request_method = GET) {
        rewrite  ^ https://$host$request_uri? permanent;
      }
      return 405;
    }
}

然后您可以添加进一步的检查以仅将您想要的流量重定向到 https。

我一直在使用以下方法:

server {
    listen      80;
    server_name www.yourdomain.com *.yourdomain.com;
    rewrite     ^ https://$server_name$request_uri? permanent;
}

如果连接是正常的 http,它所做的基本上是将连接重定向到 https(安全 ssl)。 希望对你有帮助。

已找到答案,

事实证明,可以同时拥有 HTTP 和 HTTPS 服务器并默认选择 HTTPS。我只需要将 conf 文件的两个服务器合二为一,就像:

server {
    listen 80;
    listen 443 default_server ssl;

    ssl_certificate certificate.crt;
    ssl_certificate_key server.key;

    server_name server.com;
    server_name *.server.com;
    client_max_body_size 0;
    charset utf-8;
...
}