NGINX 如何强制 http 301 跳转到 https 网上的教程都是错误的 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
miao
V2EX    NGINX

NGINX 如何强制 http 301 跳转到 https 网上的教程都是错误的

  •  
  •   miao 2015-08-21 17:25:52 +08:00 28448 次点击
    这是一个创建于 3756 天前的主题,其中的信息可能已经有所发展或是发生改变。
    诸如
    rewrite ^(.*)$ https://$host$1 permanent;
    error_page 497 https://$host$uri?$args;
    等规则试验了都不行
    都会导致循环重定向
    28 条回复    2020-02-05 19:04:34 +08:00
    closeid
        1
    closeid  
       2015-08-21 17:33:47 +08:00   1
    如果使用上面两句,需要 http 和 https 独立成两个 server 。
    SourceMan
        2
    SourceMan  
       2015-08-21 17:42:02 +08:00   1
    server {
    listen 80;
    server_name xxx.com www.xxx.com;
    rewrite ^(.*) https://xxx.com$1 permanent;
    }
    sy1989
        3
    sy1989  
       2015-08-21 17:42:35 +08:00   1
    if ($scheme = http ) {
    rewrite ^(.*)$ https://$host$1 permanent;
    }
    Jat001
        4
    Jat001  
       2015-08-21 17:44:52 +08:00   2
    listen 80;
    listen 443 ssl;

    #下面两个一样的效果
    if ($scheme = http ) {
    return 301 https://$host$request_uri;
    }

    if ($server_port = 80 ) {
    return 301 https://$host$request_uri;
    }

    #http://nginx.org/en/docs/http/ngx_http_ssl_module.html#errors
    error_page 497 https://$host$request_uri;
    Pastsong
      nbsp; 5
    Pastsong  
       2015-08-21 17:45:15 +08:00   1
    listen 80;
    listen 443;

    if ($ssl_protocol = "") { rewrite ^ https://$server_name$request_uri? permanent; }
    virusdefender
        6
    virusdefender  
       2015-08-21 17:55:47 +08:00   2
    server{
    listen 80;
    server_name virusdfefender.net;
    return 301 https://virusdefender.net$request_uri;
    }


    server {
    listen 443 ssl spdy;
    ssl on;
    server_name virusdfefender.net;
    ....
    }
    TankyWoo
        7
    TankyWoo  
       2015-08-21 18:28:43 +08:00   1
    看标题还以为楼主发现了一个惊天 bug ,然后给出一个完美的配置方案

    结果 ~~~

    楼主有质疑精神是好事,但是你想想那么多人都是那么配的,有问题的概率还是比较小啊。你怎么就能这么果断的下结论呢?

    我是直接写了两个 server, 然后一个 rewrite 做 301
    lhbc
        8
    lhbc  
       2015-08-21 18:47:26 +08:00   1
    必须两个 server
    如果只用一个 server ,然后用 if 判断协议或者端口
    每个请求都必须执行一次 if ,这多蛋疼
    salmon5
        9
    salmon5  
       2015-08-21 19:01:57 +08:00   1
    官方推荐 return 301,rewrite 复杂而且性能差。
    ryd994
        10
    ryd994  
       2015-08-21 20:15:38 +08:00   1
    @Jat001
    @sy1989
    @Pastsong
    if is evil,
    明明 return 就好,rewrite 什么,没事 regex 很好玩么?
    mchl
        11
    mchl  
       2015-08-21 20:17:12 +08:00 via Android   1
    error_page 497 https://$server_name:$server_port$request_uri;
    以上是从配置文件里直接粘贴出来的,版本 1.8.0
    shierji
        12
    shierji  
       2015-08-21 20:33:52 +08:00   1
    本来想回的。。不过上面都说的很好了。。
    Bardon
        13
    Bardon  
       2015-08-21 23:11:38 +08:00
    @mchl
    不懂,以下语句写入 443 的那个 server 中
    error_page 497 https://$server_name:$server_port$request_uri;
    告诉我, 80 那个端口怎么知道 497 状态?

    curl 测试
    $ curl -IL http://domain.com
    curl: (7 ) Failed to connect to domain.com port 80: Connection refused
    mchl
        14
    mchl  
       2015-08-21 23:17:27 +08:00 via Android
    @Bardon 哦,要把 listen 80 一行删掉,既然强制跳转 ssl ,为何还要 listen 80
    mchl
        15
    mchl  
       2015-08-21 23:18:39 +08:00 via Android
    @mchl 只要一个 server 配置
    Bardon
        16
    Bardon  
       2015-08-21 23:28:40 +08:00
    @mchl 既然没有 listen 80;
    但 http 默认为 80
    curl 实测结果就是
    curl: (7 ) Failed to connect to domain.com port 80: Connection refused
    Bardon
        17
    Bardon  
       2015-08-21 23:32:06 +08:00
    @mchl 我测试的结果是
    listen 443 spdy;
    listen 80;
    server_name domain.com;
    ......

    error_page 497 https://$server_name:443$request_uri;

    这样才行,必须告诉 nginx ,该域名的 80 端口也能访问进来
    mchl
        18
    mchl  
       2015-08-21 23:37:46 +08:00 via Android
    @Bardon 好吧,我这边网址比较特殊,端口不是默认的 80 和 443 ,访问网址必须指定端口, sorry
    lzxgh621
        19
    lzxgh621  
       2015-08-22 00:21:47 +08:00
    if ($server_port = 80 ) {
    return 301 https://$server_name$request_uri;
    }
    if ($scheme = http ) {
    return 301 https://$server_name$request_uri;
    }
    error_page 497 https://$server_name$request_uri;
    lzxgh621
        20
    lzxgh621  
       2015-08-22 00:23:23 +08:00
    单 server 一直正常 除非你的配置方式不是标准的
    RAKE
        21
    RAKE  
       2015-08-22 00:26:41 +08:00
    return 301
    当然有种更变态的方法就是开启 hsts 。。。
    ryd994
        22
    ryd994  
       2015-08-22 23:35:51 +08:00   1
    @Bardon 你贴的配置要工作,还漏了 ssl on;(顺带一提,这也是个已经废弃的选项)
    希望你在复制粘贴前能先 STFW ,而不是祈祷网上随便找来的一段字符能工作。

    如果你已经 Google 过,你应该明白:
    497 是表示客户端用 HTTP 访问了一个应该用 HTTPS 的端口时返回的非标准状态。因此 497 法本身是个非标准&过时的 hack 。要使 497 法生效,就要把 80 端口故意错误的配置成 SSL 端口。这个方法只能挂一个站。

    Again ,对 Nginx ,唯一正解就是两个 server 。 6 楼去掉那行 ssl on 就很好

    @RAKE http 访问时返回的 HSTS 是不生效的,至少 chrome 上是这样

    @lzxgh621 回复前能先读读别人的回复么? if is evil 。何况根本没必要
    Bardon
        23
    Bardon  
       2015-08-22 23:43:25 +08:00
    @ryd994 不懂你什么意思
    我确认我在 google 后,且经过实机测试的结果,你或学没有看到“...... ”,所以激动了?
    如果你认为我只是个复制粘贴党,那么我们没有共同语言
    Bardon
        24
    Bardon  
       2015-08-22 23:44:58 +08:00
    @ryd994 重新看了篇,懂你意思了,分歧在非标准端口上
    我的配置没问题
    usernametoolong
        25
    usernametoolong  
       2015-08-23 09:15:30 +08:00
    3 楼 4 楼已经给了答案
    lazyyz
        26
    lazyyz  
       2015-10-04 16:14:47 +08:00
    开 80 和 443 两个 server ,在 80 里用 return 301 就可以了
    location / {
    return 301 https://你的域名$request_uri;
    }
    q66213772
        27
    q66213772  
       2017-04-10 14:55:00 +08:00
    有只监听一个端口的方法吗?
    t5k5
        28
    t5k5  
       2020-02-05 19:04:34 +08:00
    一个万年老贴帮了我,和楼主遇到一样的问题,重定向放在了同一个 server 导致重定向无法访问。
    后来独立出来一个 server,却也没有生效。
    突然意识到,应该把重定向的 server 放前面 :(
    希望对后面搜索找寻答案的人有点帮助

    server
    {
    listen 80;
    server_name www.domain.com;
    return 301 https://www.domain.com$request_uri;
    }
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2415 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 15:52 PVG 23:52 LAX 07:52 JFK 10:52
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86