从 https 重定向到 http?

Wil*_*ons 4 ajax https nginx fullcalendar http-status-code-301

这里有奇怪的问题。我使用 FullCalendar 向服务器上的端点发起 ajax 请求。端点是:

https://my_website/events/?start=2019-03-31&end=2019-05-12&_=1555698739056

请注意,它明确是 https。但是,当我发起请求时(即当 Fullcalendar 发起请求时),我收到 301 并重定向到非 https 端点:

http://my_website/events?start=2019-03-31&end=2019-05-12&_=1555698739056

由于页面是通过 https 加载的,因此失败。

在此输入图像描述

端点工作正常 - 当我将其加载到浏览器中时,我得到了预期的 json 输出(通过 https)。此页面上发生的其他 ajax 请求可以正常工作,并且我成功地在本网站其他地方(到另一个端点)使用 Fullcalendar 执行了完全相同的操作。只是这一种情况的表现出乎意料。

可能值得注意的是,它位于 nginx 反向代理/负载均衡器后面的 docker 容器中;站点配置非常简单:

upstream docker {
    server localhost:8701;
    server localhost:8702;
  }

server {
    server_name my_website;
    location / {
      proxy_pass http://docker;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
      # proxy_set_header                HTTP_Country-Code $geoip_country_code;
        proxy_pass_request_headers      on;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/my_website/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/my_website/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

server {
    if ($host = my_website) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80;
    server_name my_website;
    return 404; # managed by Certbot

}
Run Code Online (Sandbox Code Playgroud)

而nginx的请求日志是这样的:

134.124.11.91 - - [19/4/2019:13:49:49 -0500]“GET /events/?start=2019-04-28&end=2019-06-09&_=1555699678658 HTTP/1.1”301 0“https : //my_website " "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, 如 Gecko) Chrome/73.0.3683.103 Safari/537.36"

有人看到我遗漏的东西会导致这个奇怪的 301 重定向到非 https 端点吗?

cns*_*nst 5

问题

发生这种情况的原因似乎是您没有使用规范 URL,而您的后端通过这些301重定向强制执行此类 URL,而它实际上并不知道规范地址方案。


解决方案

  • 最好的解决方案是修复前端代码以始终使用规范 URL。例如,在您提供的示例中,API 端点中是否存在尾部斜杠存在差异。

  • 您可能应该配置您的后端,使其正确意识到它是通过 访问的https,例如,在 nginx 中的所有其他指令旁边添加类似以下内容的内容proto_set_header,以终止 https 并将流量传递到后端:

    proto_set_header    X-Forwarded-Proto   $scheme;
    
    Run Code Online (Sandbox Code Playgroud)

其他想法

  • 另一个解决方案是配置http://nginx.org/r/proxy_redirect以正确识别后端返回的本地Location标头,并根据需要即时转换它们;但是,对于您的情况,前两个选项可能是更好的方法。