La regla de reescritura con QUERY_STRING no funciona

Oct 22 2020

En el servidor Apache, necesito reescribir mydomain.com/something/?p=value en mydomain.com/something/?page=value

Lo intenté:

RewriteEngine On
RewriteCond %{QUERY_STRING} p=(.*)
RewriteRule ^(.*)/p=$ $1?page=%{QUERY_STRING} [L,QSA]

pero no wok, ¿me pueden ayudar?

Respuestas

1 MrWhite Oct 22 2020 at 14:13
RewriteCond %{QUERY_STRING} p=(.*)
RewriteRule ^(.*)/p=$ $1?page=%{QUERY_STRING} [L,QSA]

Hay numerosos "errores" aquí:

  • El RewriteRule patrón , es decir. ^(.*)/p=$, nunca coincidirá porque p=no aparece como parte de la ruta de URL (es parte de la cadena de consulta). El RewriteRule patrón coincide solo con la ruta de la URL, lo que excluye notablemente la cadena de consulta. Entonces, lo anterior no hará nada para la URL de ejemplo indicada.

  • Está utilizando la QUERY_STRINGvariable de servidor en lugar del parámetro de URL requerido valueen la cadena de sustitución . Pero QUERY_STRINGes, obviamente, toda la "cadena de consulta", por lo que terminaría la construcción de una cadena de consulta con formato incorrecto de la forma: page=p=<value>.

  • El uso de la QSAmarca da como resultado que la cadena de consulta original de la solicitud se combine con la cadena de consulta que está utilizando en la cadena de sustitución . Entonces, esto resultaría en &p=<value>ser agregado, que no es lo que necesita. Está buscando reemplazar la cadena de consulta existente.

  • RewriteRule ^(.*)/p=$ $1?page=- Está excluyendo la barra al final del grupo de captura en el RewriteRule patrón , por lo que esto eliminaría efectivamente la barra al final de la URL reescrita. Esto es diferente a tu ejemplo.

  • Parece que necesita una reescritura interna (sin redireccionamiento externo ) y "solo" está cambiando el nombre de un único parámetro de URL. Esto es algo que normalmente resolvería en su aplicación, en lugar de una reescritura de URL en Apache. (?)

En su lugar, intente lo siguiente:

RewriteEngine On

# Internally "rewrite" the request
RewriteCond %{QUERY_STRING} ^p=([^&]*)$
RewriteRule (.*/)$ $1?page=%1 [L]

Esto coincide con cualquier ruta de URL que termine en una barra (según su ejemplo). La %1referencia inversa se refiere al grupo capturado en el último CondPattern coincidente , es decir. el valor del pparámetro de URL. Se supone que p=<value>es el único parámetro de URL de la solicitud.


ACTUALIZACIÓN: parece que no funciona ... si llamo localhost/list/?p=2simplemente obtengolocalhost/list/?p=2

Sí, la URL visible no cambia, ya que se trata de una "reescritura" interna (como parece estar solicitando en su pregunta). La URL se reescribe internamentelist/?page=2 . (También existe el punto que list/?page=2no es estrictamente un punto final válido; requiere una reescritura adicional, tal vez mediante mod_dir para formar una solicitud válida. list/index.php?page=2¿Por ejemplo ?)

Si desea que la URL cambie visiblemente, ¿tal vez necesite una "redirección" externa después de todo? Para esto, debe incluir un prefijo de barra en la cadena de RewriteRule sustitución y agregar el indicador R( redirect). Por ejemplo:

# Externally "redirect" the request
RewriteCond %{QUERY_STRING} ^p=([^&]*)$ RewriteRule (.*/)$ /$1?page=%1 [R=302,L]

si modifico la regla para obtener localhost/list/?p=2&?p=2lo siguiente:

RewriteEngine On
RewriteCond %{QUERY_STRING} ^p=([^&]*)$
RewriteRule (.*/)$ $1&?page=%1 [L]

obtengo 'La URL solicitada /list/&no se encontró en este servidor'. como '?' cortar la reescritura

Si lo solicita localhost/list/?p=2&?p=2(pero ¿por qué?), Las directivas anteriores no harán nada en absoluto, ya que la condición no coincidirá.

¿Por qué agregaste a &en la cadena de RewriteRule sustitución ? (¿Eso no tiene sentido?) Eso daría como resultado una ruta URL del formulario /list/&, si se procesara la regla. Pero, como se indicó, ¿no se procesaría para la URL que indicó?