Чтобы отразить весь веб-сайт как статический HTML,
Я хотел бы преобразовать URL-адреса типа http://example.com/script.php?t=12
к http://example.com/script.php_t=12
.
Уведомление ?
в URL преобразуется в _
.
Это позволит nginx или apache обслуживать эти файлы с диска как необработанный HTML-код, который мы получили и сохранили из wget
- один файл для каждого URL-адреса, а не как файл PHP.
Можно ли сделать это с помощью перезаписи URL-адресов Nginx?
Я получил эту работу с помощью try_files:
location / {
try_files "${uri}_${args}" 404.html;
}
Это попытается найти на диске файл, названный в соответствии с указанным вами шаблоном с «_» вместо «?».
Дальнейшая конфигурация зависит от того, как вы сохранили статические файлы, такие как изображения или таблицы стилей. Вы можете добавить резервный вариант, пытаясь прочитать их без диска формы строки запроса, например:
location / {
try_files "${uri}_${args}" $uri 404.html;
}
Что-то вроде:
location ~ \.php$ {
# only rewrite URL's with args
if ($args != '') {
rewrite .* "${uri}_${args}?" last;
}
}
Я не думаю, что вы сможете сделать это с помощью vanilla nginx, но если вы хотите установить модуль Lua для nginx (http://wiki.nginx.org/HttpLuaModule) ты можешь это сделать.
server {
server_name so.dev;
listen 80;
location / {
root /tmp;
rewrite_by_lua '
local uri = ngx.var.uri
local params = ngx.req.get_uri_args(0)
for key, value in pairs(params) do
uri = string.format("%s_%s=%s", uri, key, value)
end
ngx.req.set_uri(uri)
ngx.req.set_uri_args({})
';
}
}
Протестировал локально и, похоже, делает то, что вы ищете. Если вы хотите, чтобы другие параметры были разделены амперсандами, измените блок rewrite_by_lua на
local uri = ngx.var.uri
local param_string = ""
local params = ngx.req.get_uri_args(0)
local separator = ""
for key, value in pairs(params) do
param_string = param_string .. separator .. key .. "=" .. value
separator = "&"
end
ngx.req.set_uri(uri .. "_" .. param_string)
ngx.req.set_uri_args({})
Это работает на nginx / 1.6.2.
rewrite ^/.*\.php$ "${uri}_${args}";
Но лично я бы использовал try_files
решение с откатом к исходному URI если есть.
try_files $uri "${uri}_${args}";
Например. если у вас есть script.php
на диске он сначала попробует с ним, а затем, если его нет, он пойдет script.php_t=12
. try_files
нужна последняя версия nginx.
А если этого недостаточно, можно сделать это внутри if
:
return 301 "${uri}_${args}";
В вики говорит
Если вы укажете? в конце перезаписи Nginx отбросит исходные $ args (аргументы).
Итак, тогда rewrite ^ ${uri}_$args? last;
должно сработать.
Предложенные выше ответы должны работать. Однако вы видите, насколько чувствительным становится ваш URL. Поскольку nginx сначала пытается проверить, существует ли имя файла на сервере, любой дополнительный параметр отбросит его.
http://example.com/script.php?t=12 // works
http://example.com/script.php?t=12&_utm=twitter // not work
Я предлагаю оставить URL как есть и направить его в файл с помощью php. У вас есть доступ к t
параметр.