With nginx/php-fpm, location header sometimes igno

2019-02-20 12:51发布

I'm in the process of moving a working apache/mod-php website to nginx/php-fpm.

Under Apache/mod-php, I could use header("Location: $url"); to redirect the browser to a different page, such as after a login attempt. After switching to nginx/php-fpm, the browser would no longer follow that redirect on certain pages. I confirmed with Firebug and Httpfox that the header "Location: [url]" was actually being received in the response. This behavior also appears in Chrome (not tested in IE).

So I did a few experiments, read a few things about http, and made it work, but I'm not sure why it works (or why it didn't).

The solution I came up with was to send a "Status: 303" header before the "Location: [url]" header. This works in Chrome and Firefox, which both ignored the Location header when I sent "Status: 200" or omitted the Status header, but did the redirect when I changed it to "Status 303". It worked with Status 200 under Apache.

Is the Status header required to use the Location header? Or was Apache doing something else to make it work? I've not changed any of the php code involved other than the header("Status: 303"); line that made it work. There has to be something else at work here, but I have no clue what it could be.

Any ideas?

1条回答
Summer. ? 凉城
2楼-- · 2019-02-20 13:44

The Location header does not, by itself, trigger the browser to redirect. The redirect is actually triggered by an HTTP response code that is in the 3xx series. w3c has explanations for all http response codes.

Apache automatically sees the Location header in the response, and forces the response code to be 300-series if you haven't previously set a response code of your own. Nginx does not do this -- it expects you set the proper response code yourself.

You can force php to send a modified HTTP response code like this:

<?php
  header("HTTP/1.0 301 Moved Permanently");
?>

...Then, of course, you'll need to be sure you still sent your Location header after sending the HTTP/1.0... line shown above.

查看更多
登录 后发表回答