web-dev-qa-db-ja.com

nginx変数文字列の文字を置き換える方法は?

$request_uriで返された英数字以外の文字をスペース(または+)に置き換える方法はありますか?

私がやろうとしていることは、私のサイトの1つにあるすべての404をその検索エンジンにリダイレクトすることです。クエリはuriが要求されたものです。だから、私は私のnginx.confに以下を含むブロックを持っています:

error_page 404 = @notfound;
location @notfound {
    return 301 $scheme://$Host/?s=$request_uri;
}

これは実際に機能しますが、返されるURLは実際のuriであり、-_/文字で完了しているため、検索では常に0の結果が返されます。

たとえば、次のURLを指定します:https://example.com/my-articles、リダイレクトは次のようになります:https://example.com/?s=/my-articles

私が望むのは、最終的には(最終的に)次のようになることです:https://example.com/?s=my+articles(そう、最初の+もうまくいきます... https://example.com/?s=+my+articles

LUAまたはPerlモジュールなしでこれを行う必要があります。それで、どうすればこれを達成できますか?

3
Kevin

ディレクトリ構造をどれだけ下に移動するかによって、これを微調整する必要がある場合がありますが、これは基本的な概念です。

404の最初のキャプチャの名前付き場所:

location @notfound {
  rewrite (.*) /search$1 last;
}

名前付きの場所は少し制限があるので、これは404を返したURIの先頭に/search/を追加するだけです。lastフラグは、現在の場所から抜け出し、最適な場所を選択するようにNginxに指示します書き換えられたURIに基づいてリクエストを処理するには、それをキャッチするためのブロックが必要です。

location ^~ /search/ {
  internal;
  rewrite ^/search/(.*)([^a-z0-9\+])(.*)$ /search/$1+$3 last;
  rewrite ^/search/(.*)$ /?s=$1 permanent;
}

internalディレクティブは、この場所にNginxプロセス自体のみがアクセスできるようにします。このブロックへのクライアント要求は404を返します。

最初の書き換えでは、最後の非テキスト、数字、または+文字を+に変更し、Nginxに書き換えられたURIの再評価を依頼します。

ロケーションブロックは^~修飾子で定義されます。つまり、このロケーションに一致するリクエストは、正規表現で定義されたロケーションブロックに対して評価されないため、このブロックは書き換えられたリクエストをキャッチし続ける必要があります。

Word以外の文字がすべてなくなると、最初の書き換えは一致しなくなるため、リクエストは次の書き換えに渡され、URIの前部から/searchが削除され、クエリ文字列が追加されます。

私のログは次のようになります:

>> curl -L -v http://127.0.0.1/users-forum-name.1
<<  "GET /?s=users+forum+name+1 HTTP/1.1"

>> curl -L -v http://127.0.0.1/users-forum-name/long-story/some_underscore
<< "GET /?s=users+forum+name+long+story+some+underscore"

あなたはアイデアを得ます。

1
miknik
  1. 404 Not Foundページから別の場所へのリダイレクトを自動的に発行することは、一般的に悪い考えです。ユーザーは、URLに単一の文字を誤って入力した可能性があります(たとえば、携帯電話で、チラシからURLをコピーし、「ファットフィンガー」)。これは、アドレスバーに404と明らかなタイプミスが見つかれば修正が非常に簡単ですが、検索エンジンが配信しない場合は、ゼロから始める必要がある場合があります。

  2. それでもやりたい場合は、検索エンジン自体の中で行う方が効率的かもしれません。結局のところ、検索エンジンがURLによる検索とタイプミスの修正ができない場合は、非常に便利な検索エンジンです。

  3. それでも検索エンジンの前のnginx内でそれを実行したい場合は、 http://nginx.org/r/rewrite ディレクティブを使用すると、基本的にあらゆるソートを実装できるという事実を使用できますDFAの決定性—確定的有限オートマトン—ただし、必要な置換の数によっては、サイクルが多すぎたり、やや柔軟性のないルールセットになる可能性があります。

    URL内の特定の文字を他の文字に再帰的に置換する方法については、次のリソースをご覧ください。

0
cnst

Luaモジュールを使用して、この変数をlua文字列関数を使用して必要なものに変換できます。私はOpenRestyを使用していますが、これは基本的にnginxでluaが有効になっています。しかし、nginx luaモジュールは問題なく動作します。 nginx構成内でluaを使用できるようにするディレクティブは次のとおりです。 content_by_lua_block/access_by_lua_blockを使用して場所内に配置することも、content_by_lua_file/access_by_lua_fileを使用して別のファイルに配置することもできます。これは https://github.com/openresty/lua-nginx-module#content_by_lua に関するドキュメントです。これが私のアプリの例です。

location ~/.*\.jpg$ {

  set $test '';
  access_by_lua_block {

    ngx.var.test = string.sub(ngx.var.uri, 2)

  }
  root /var/www/luaProject/img/;
  try_files    $uri /index.html;


  }
0
Donm