V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
NGINX
NGINX Trac
3rd Party Modules
Security Advisories
CHANGES
OpenResty
ngx_lua
Tengine
在线学习资源
NGINX 开发从入门到精通
NGINX Modules
ngx_echo
YuuuZeee
V2EX  ›  NGINX

关于 Nginx 将 post 请求转化为 get 请求的问题

  •  
  •   YuuuZeee · 2018-07-15 14:12:54 +08:00 · 7663 次点击
    这是一个创建于 2104 天前的主题,其中的信息可能已经有所发展或是发生改变。

    RT,最近在部署一个 Django 的服务器的时候,发现如果 Django 用的是默认的 http, 然后 nginx 强行转成 https 的时候, 所有发给服务器的 POST 请求会变成 GET 请求。 后来 google 了半天,又和运维大佬看了半天,发现解决方案是加一条 return 307 https://$host$request_uri;

    307 跳转。但是个人还是不是很理解为什么会这样=-=哪位大佬能帮忙解释下

    9 条回复    2018-07-16 04:58:32 +08:00
    YuuuZeee
        1
    YuuuZeee  
    OP
       2018-07-15 14:14:23 +08:00
    相关内容: https://tools.ietf.org/html/rfc7231#section-6.4.2
    Note: For historical reasons, a user agent MAY change the request
    method from POST to GET for the subsequent request. If this
    behavior is undesired, the 307 (Temporary Redirect) status code
    can be used instead.

    但是我就不理解咋变成 undesired 了=-=
    ysc3839
        2
    ysc3839  
       2018-07-15 14:44:21 +08:00 via Android
    之前看一本书《图解 HTTP 》有提到,HTTP 标准规定 302 跳转不应该更改请求方式,但是可能是历史遗留问题,浏览器会把请求改为 GET,使用 307 跳转的话才不会改变。
    tomczhen
        3
    tomczhen  
       2018-07-15 14:51:19 +08:00
    这不是 Nginx 转换的,而是 HTTP Client 根据 Nginx 返回的状态码再次发出请求,直白的说:最终的请求方式不是 Server 端能保证的。

    Web 端需要看浏览器的支持,如果是应用 API 则需要看应用使用的请求库支持。

    如果想保证最终结果,可以使用 nginx lua/OpenResty 脚本实现逻辑转换。
    tomczhen
        4
    tomczhen  
       2018-07-15 14:53:43 +08:00   ❤️ 5
    补充一下,根据你的描述看,应该用反代解决,而不是重定向。

    现在当大佬真容易啊,唉。
    yyfearth
        5
    yyfearth  
       2018-07-15 17:31:54 +08:00   ❤️ 2
    对啊 这里不应该用 302 或者 307 重定向
    https server 应该直接 proxy_pass http:
    你需要把 Django 默认的 http 改成 https
    只有 Django 的页面 如果是 http 来的 302/301 到 https
    POST 请求的页面 必须直接是 https 不然就没有意义了

    nginx 要这样配置
    http server: GET 302/301 redirect to https url
    https server: GET/POST/etc proxy_pass http://django-server

    比如你进入 http 首页 然后 301/302 跳转到 https 首页 这里肯定是 GET 所以没问题
    然后 https 页 POST 到一个 http 页面 然后这个页面再自己 307 到 https 这样就没有意义了
    必须设置成 https POST 到 https 上面才行
    mikeguan
        6
    mikeguan  
       2018-07-15 18:37:48 +08:00 via Android
    之前也遇到过 方法同样是换成 307
    caola
        7
    caola  
       2018-07-15 18:57:27 +08:00
    307 是临时的相当于 302, 308 是永久定向相当于 301
    mikeguan
        8
    mikeguan  
       2018-07-15 19:46:55 +08:00 via Android
    @tomczhen 我觉得他的描述更像是将 http 重定向到 https,还是开 hsts 比较好
    msg7086
        9
    msg7086  
       2018-07-16 04:58:32 +08:00
    > If this behavior is undesired

    你是对这句英语的中文意思抱有疑问吗?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   943 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 21:07 · PVG 05:07 · LAX 14:07 · JFK 17:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.