Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

357
Views
No se pueden usar paréntesis en RewriteCond QUERY_STRING

Se movió de https://serverfault.com/questions/1013461/cant-use-parentheses-in-rewritecond-query-string porque es un tema aquí.


Necesito capturar un UID de una URL antigua y redirigirlo a un nuevo formato.

example.com/?uid=123 debe redirigir a example.com/user/123

Lo que debería funcionar:

 RewriteCond %{QUERY_STRING} ^uid=(\d+)$ RewriteRule ^$ /user/%1? [L]

Esto no redirige en absoluto.

Sin embargo, esto hace:

 RewriteCond %{QUERY_STRING} ^uid=\d+$ RewriteRule ^$ /user/%1? [L]

Va a example.com/user . El UID se omite, pero SÍ redirige.

Aviso: todo lo que hice fue eliminar los paréntesis en el segundo ejemplo.

¿¿Por qué es esto?? ¿Cómo puedo hacer coincidir la consulta Y capturar el valor de UID?


Actualizaciones

Esta es una aplicación laravel. Descubrí que los redireccionamientos que vi pueden provenir de la aplicación, no de Apache.

Auto-respuesta próximamente...

Agregar temporalmente R = 302 da el resultado deseado:

 RewriteCond %{QUERY_STRING} ^uid=(\d+)$ RewriteRule ^$ /user/%1? [L,R=302]

Esto, por supuesto, envía una redirección 302 a /users/123 . Sin embargo, me gustaría ver si esto se puede hacer con una reescritura interna ...

Aquí hay algunas reglas en el .htaccess predeterminado de laravel:

 # Handle Front Controller... RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L]

Esto detecta rutas que no apuntan a archivos reales y las dirige a la aplicación laravel. Cuando se elimina, Apache responde con un 404 para /users/1234.

https://httpd.apache.org/docs/2.4/rewrite/flags.html#flag_l

Tal reescritura se remonta al analizador de URL de Apache. Luego, el .htaccess se vuelve a procesar (ya que todavía es aplicable a esta nueva URL). En este punto, espero que las reglas anteriores tomen la ruta inexistente y la apunten a la aplicación laravel...

Lo encontré. Escribiendo una respuesta ahora.

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

La respuesta

Sr. White tenía razón. Tienes que agregar R=302 o R=301 para realizar una redirección. Una simple reescritura no funcionará.

 RewriteCond %{QUERY_STRING} ^uid=(\d+)$ RewriteRule ^$ /user/%1? [L,R=302]

La razón

Entonces, la forma en que funciona Laravel es:

  • usted solicita /some/file
  • .htaccess le dice a apache, "oye, apache, si tienes una solicitud de un archivo que no existe, simplemente finge que es para index.php "
  • apache dice: "oye, php, tengo una solicitud para ejecutar index.php y la URL es /some/file "
  • php ejecuta el script que --whoah-- es una gran aplicación laravel
  • lo que sea, "oye, laravel, el servidor dijo que /some/file es la url"
  • laravel hace todas sus cosas sofisticadas e intenta hacer coincidir la URL con una de sus rutas

Ahora, agregué una regla para reescribir una determinada URL en una URL virtual que Laravel debería manejar. Estaba haciendo coincidir los parámetros de consulta, pero eso era irrelevante. (ver más abajo para más detalles)

Cuando el módulo de reescritura de Apache alcanza una regla de reescritura sin un indicador [R], reescribe la URL y la envía de vuelta al controlador de URL. El controlador de URL de Apache luego procesa la nueva URL contra todas las reglas, incluidas las de cualquier archivo .htaccess aplicable.

Así que se aplicaron todas las reglas apropiadas.

Aquí está la revelación clave: la URL solicitada originalmente nunca cambió. Entonces, si bien Apache pudo pasar la solicitud a PHP con el archivo correcto, también envió la URL anterior.

Por lo tanto, tenemos que decirle a Apache que envíe una respuesta de redirección 301 o 302, en lugar de simplemente reescribir la solicitud . El usuario enviará otra solicitud con la URL que necesita Laravel para resolver la ruta.


Pero, ¿qué pasa con el comportamiento diferente con/sin paréntesis?

La respuesta se encuentra dentro del .htaccess predeterminado de Laravel. Echemos un vistazo a mis viejas reglas sin paréntesis:

 RewriteCond %{QUERY_STRING} ^uid=\d+$ RewriteRule ^$ /user/%1? [L]

Sin el paréntesis para obtener el valor de uid, %1 está vacío. Entonces terminamos reescribiendo la URL a solo /user/ .

Ahora, tenemos que mirar otro conjunto de reglas de Laravel:

 RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)/$ /$1 [L,R=301]

Esto normaliza las direcciones URL para que las rutas/rutas virtuales no contengan barras inclinadas al final. Hacer esto facilita el análisis de rutas.

Esto devuelve una redirección 301 a '/usuarios'. Esto es muy diferente de los 200 que obteníamos con los paréntesis, pero no significa que los paréntesis se comportaran de manera diferente. Como dijo MrWhite en los comentarios, seguramente algo más lo estaba haciendo.

Espero que hayas disfrutado el viaje. Y espero aún más que esto salve a alguna pobre alma confundida de horas de tormento. :)

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!