从https重定向到http?

问题描述 投票:4回答:2

这里有个奇怪的问题。我使用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加载的,因此失败。

enter image description here

端点工作正常 - 当我将其加载到浏览器中时,我得到了预期的json输出(通过https)。此页面上还有其他ajax请求正常运行,并且我在此站点的其他位置(到另一个端点)与Fullcalendar成功完成相同的操作。只是这一个场景表现得出乎意料。

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

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

}

并且请求的nginx日志是这样的:

134.124.11.91 - - [19 / Apr / 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端点?

ajax nginx https fullcalendar http-status-code-301
2个回答
4
投票

Problem

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


Solution

  • 最佳解决方案是修复前端代码以始终使用规范URL。例如,在您提供的示例中,API端点中是否存在尾部斜杠存在差异。
  • 您可能应该将后端配置为正确地知道它是通过https访问的,例如,在您的nginx中的所有其他proto_set_header指令旁边添加类似下面的内容,终止https并将流量传递给后端: proto_set_header X-Forwarded-Proto $scheme;

Other thoughts

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

1
投票

我不完全确定,因为你的截图有点矛盾,但是这里有:

在您的检查器屏幕截图中,我们看到一个请求https(已取消)和一个请求http(由于混合协议而被阻止)。提示是取消的,被取消意味着没有重定向,但浏览器认为它不再需要请求。以前有几个问题有类似问题,请参阅herehere两个例子。

请求被取消的一个原因是,用于更改FullCalendar日期的按钮/输入/链接不仅仅是执行ajax请求而且还执行第二个http请求(因为包装表单,href等)。你还没有包含你的FullCalendar实现的html和JavaScript,所以我肯定不知道这一点,但检查你是否有一个围绕input元素的表单,或者如果你编写了自己的事件处理程序,请执行以下操作。

function(e){
  e.preventdefault(); 

  .... // your date switching code here 

  return false;
}

如果您使用带有onclick属性的链接,请确保在末尾添加...(yourcode);return false;

重要提示:如果我的理论是正确的,这意味着日志中的行实际上与我们在检查器中看到的相同,实际上是从HTTP到HTTPS的重定向,而不是相反。这很难看,因为默认情况下nginx不会在日志中包含请求协议。

© www.soinside.com 2019 - 2024. All rights reserved.