web-dev-qa-db-fra.com

Comment remplacer des caractères dans une chaîne de variable nginx?

Est-il possible de remplacer les caractères non alphanumériques renvoyés par $request_uri par un espace (ou un +)?

Ce que j'essaie de faire est de rediriger tous les 404 de l'un de mes sites vers son moteur de recherche, où la requête correspond à la uri demandée. Donc, j'ai un bloc dans mon nginx.conf contenant:

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

Bien que cela fonctionne, les URL renvoyées sont celles de uri avec les caractères -_/, ce qui a pour résultat que la recherche renvoie toujours 0 résultats.

Par exemple ... donnez cette URL: https://example.com/my-articles, la redirection se termine comme ceci: https://example.com/?s=/my-articles

Ce que je voudrais, c'est finir (finalement) comme ceci: https://example.com/?s=my+articles (mais le + au début fonctionne très bien aussi ... https://example.com/?s=+my+articles

Je devrai le faire sans modules LUA ou Perl. Alors, comment puis-je accomplir cela?

2
Kevin

Vous devrez peut-être modifier cela en fonction de la structure de votre répertoire dans laquelle vous souhaitez que le remplacement aille, mais c'est le concept de base.

Emplacement désigné pour la capture initiale de 404:

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

Les emplacements nommés étant un peu limitants, il ne fait qu'ajouter /search/ au début de l'URI qui a renvoyé 404. L'indicateur last indique à Nginx de sortir de l'emplacement actuel et de sélectionner le meilleur emplacement pour traiter la demande en fonction de l'URI réécrit. , nous avons donc besoin d’un bloc pour attraper cela:

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

La directive internal rend cet emplacement uniquement accessible au processus Nginx lui-même. Toute demande client à ce bloc renverra 404.

La première réécriture changera le dernier caractère non textuel, chiffre ou + en un +, puis demandera à Nginx de réévaluer l'URI réécrit.

Le bloc d'emplacement est défini avec le modificateur ^~, ce qui signifie que les requêtes correspondant à cet emplacement ne seront pas évaluées par rapport à des blocs d'emplacement définis par une expression rationnelle. Ce bloc doit donc continuer à intercepter les requêtes réécrites.

Une fois que tous les caractères autres que Word ont disparu, la première réécriture ne correspond plus. La demande est donc transmise à la prochaine réécriture, ce qui supprime le /search situé au début de l'URI et ajoute la chaîne de requête.

Mes journaux ressemblent à ceci:

>> 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"

Vous avez eu l'idée..

1
miknik
  1. Il est généralement déconseillé d’émettre automatiquement des redirections à partir de pages 404 Not Found vers un autre site - l’utilisateur peut simplement avoir mal saisi un seul caractère dans l’URL (par exemple, sur un téléphone portable tout en copiant l’URL depuis un dépliant et en ayant un gros doigt). , ce qui serait très facile à corriger une fois qu’ils ont vu un 404 et la faute de frappe évidente dans la barre d’adresses, mais peut nécessiter de repartir à zéro si votre moteur de recherche ne donne pas les résultats escomptés.

  2. Si vous souhaitez toujours le faire, il serait peut-être plus efficace de le faire dans le moteur de recherche lui-même. Après tout, si votre moteur de recherche n'est pas capable de rechercher par URL et de corriger les fautes de frappe, cela ne ressemble pas à un moteur de recherche très utile, maintenant?

  3. Si vous voulez toujours le faire dans le nginx seul devant le moteur de recherche, vous pouvez utiliser le fait que les directives http://nginx.org/r/rewrite vous permettent essentiellement de mettre en œuvre toute sorte de DFA. - Automate fini déterministe - mais, en fonction du nombre de remplacements requis, il peut en résulter un trop grand nombre de cycles et d’ensembles de règles peu rigides.

    Consultez les ressources suivantes sur les remplacements récursifs de caractères donnés dans l'URL d'autres caractères:

0
cnst

Vous pouvez utiliser le module Lua, transformer cette variable en ce dont vous avez besoin à l’aide des fonctions de chaîne Lua. J'utilise OpenResty, qui est essentiellement nginx avec lua activé. Mais le module nginx lua fera l'affaire. Voici la directive qui vous permet d’utiliser Lua dans la configuration de Nginx. Il peut s'agir d'un emplacement intérieur utilisant content_by_lua_block/access_by_lua_block ou d'un fichier séparé utilisant content_by_lua_file/access_by_lua_file. Voici la documentation sur ce https://github.com/openresty/lua-nginx-module#content_by_lua . Voici un exemple tiré de mon application. 

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