2010-07-13 13 views
64

Sobre el sistemaurlencoded Barra inclinada está rompiendo URL

que tienen direcciones URL de este formato en mi proyecto: -

http://project_name/browse_by_exam/type/tutor_search/keyword/class/new_search/1/search_exam/0/search_subject/0 

Dónde par de palabras clave/clase significa búsqueda con la palabra clave "clase".

Tengo un archivo index.php común que se ejecuta para cada módulo en el proyecto. Sólo hay una regla de reescritura para eliminar el index.php desde la URL: -

RewriteCond $1 !^(index\.php|resources|robots\.txt) 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule ^(.*)$ index.php [L,QSA] 

estoy usando urlencode() mientras se prepara la URL de búsqueda y urldecode(), mientras que la lectura de la URL de búsqueda.

Problema

Sólo el carácter de barra diagonal está rompiendo URL causando 404 página no se encuentra el error. Por ejemplo, si la búsqueda one/two la URL es

http://project_name/browse_by_exam/type/tutor_search/keyword/one%2Ftwo/new_search/1/search_exam/0/search_subject/0/page_sort/ 

¿Cómo puedo solucionar esto? Necesito mantener index.php oculto en la URL. De lo contrario, si eso no era necesario, no habría habido ningún problema con la barra inclinada y podría haber utilizado este URL: -

http://project_name/index.php?browse_by_exam/type/tutor_search/keyword/one 
%2Ftwo/new_search/1/search_exam/0/search_subject/0 
+1

Siento que lo mejor es tener URLs como esta: - 'http: // nombre_del_proyecto/browse_by_exam? Type/búsqueda_prueba/palabra clave/clase% 2Fnew/new_search/1/search_exam/0/search_subject/0' De esa forma me deshago de lo difícil y de legibilidad causada por & param1 = value1 & param2 = value2 convención y también puedo permitir barras diagonales (ahora en la parte de la cadena de consulta usando '?') Evitaré AllowEncodedSlashes porque Bobince dijo 'También podrían obtenerse algunas herramientas o arañas confundido por eso. Aunque% 2F significa/en una parte de ruta es correcta según el estándar, la mayoría de la web lo evita. url .htaccess url-routing –

+1

puede usar% 2F si se usa de esta manera? Param1 = value1 & param2 = value% 2Fvalue pero si usa/param1 = value1/param2 = value% 2Fvalue lanzará un error. – Ahmad

+0

Relacionado: [Es una barra diagonal ("/") equivalente a una barra diagonal codificada ("% 2F") en la porción de ruta de una URL HTTP] (http://stackoverflow.com/q/1957115/95735) –

Respuesta

129

Apache niega todas las URL con %2F en la parte de la ruta, por razones de seguridad: Los scripts pueden normalmente (es decir, sin reescribir) indique la diferencia entre %2F y / debido a que la variable de entorno PATH_INFO se decodifica automáticamente mediante URL (lo cual es estúpido, pero una parte antigua de la especificación CGI por lo que no se puede hacer nada al respecto)

Usted puede desactivar esta función mediante la directiva AllowEncodedSlashes, pero tenga en cuenta que otros servidores web todavía no permitir que (sin la opción de apagar eso), y que otros personajes también pueden ser un tabú (por ejemplo. %5C), y que el %00 en particular siempre estará bloqueado tanto por Apache como por IIS. Entonces, si su aplicación dependía de poder tener %2F u otros caracteres en una parte de la ruta, estaría limitando sus opciones de compatibilidad/implementación.

estoy usando urlencode() mientras se prepara la URL de búsqueda

Debe utilizar rawurlencode(), no urlencode() para escapar partes de trayectoria. urlencode() está mal llamado, en realidad se trata de datos application/x-www-form-urlencoded, como en la cadena de consulta o en el cuerpo de una solicitud POST, y no para otras partes de la URL.

La diferencia es que + no significa espacio en las partes de ruta. rawurlencode() producirá correctamente %20 en su lugar, que funcionará tanto en datos codificados en formulario como en otras partes de la URL.

+4

Ah, así que esa es la razón por la cual la barra obvia es denegada. Diagnóstico y tratamiento perfectos –

+1

+1 Intenté explicar algo de esto en una de sus otras preguntas, pero lo hizo mucho más coherentemente de lo que pude. –

+3

Hola Bobince, 'rawurlencode()' también convierte las barras diagonales en '% 2F', que todavía está rompiendo mi URL. No entendí realmente cómo 'rawurlencode()' solucionó mi problema. –

4

En Apache, AllowEncodedSlashes En impediría que la solicitud sea rechazada inmediatamente con un 404.

Sólo otra idea sobre cómo solucionar este problema.

2

En mi cuenta de alojamiento este problema fue causado por una regla ModSecurity que se estableció para todas las cuentas automáticamente. Al informar este problema, su administrador eliminó rápidamente esta regla para mi cuenta.

-3

Puede utilizar %2F si se utiliza de esta manera:
?param1=value1&param2=value%2Fvalue

pero si se utiliza /param1=value1/param2=value%2Fvalue se generará un error.

3
$encoded_url = str_replace('%2F', '/', urlencode($url)); 
0

una solución estándar para este problema es permitir que las barras, haciendo que el parámetro que puede contener recorta el último parámetro en la URL.

para una dirección URL código de producto que tendría entonces ...

mysite.com/product/details/PR12345/22 

Por un término de búsqueda que tendría

http://project/search_exam/0/search_subject/0/keyword/Psychology/Management 

(La palabra clave aquí es la psicología/Gestión)

No es una gran cantidad de trabajo procesar los primeros parámetros "nombrados" y luego concat los restantes para ser código de producto o palabra clave.

Algunos marcos tienen esta función incorporada a sus definiciones de enrutamiento.

Esto no se aplica al caso de uso que involucre dos parámetros que mi contiene barras inclinadas.

3

Reemplazar% 2F con% 252F después url codificación

PHP

function custom_http_build_query($query=array()){ 

    return str_replace('%2F','%252F', http_build_query($query)); 
} 

manejar la petición a través de htaccess

.htaccess

RewriteCond %{REQUEST_URI} ^(.*?)(%252F)(.*?)$ [NC] 
RewriteRule . %1/%3 [R=301,L,NE] 

Recursos

http://www.leakon.com/archives/865

+0

¡La mejor solución! –

-1

utilizo función javascript encodeURI() para la parte URL que tiene barras diagonales que debe ser visto como caracteres en lugar de la dirección http. Ej:

"/api/activites/" + encodeURI("?categorie=assemblage&nom=Manipulation/Finition") 

ver http://www.w3schools.com/tags/ref_urlencode.asp

+0

el problema está en manejar el URI después de que está codificado en% 2F - ver la respuesta aceptada 'Apache niega todas las URL con% 2F en la parte de la ruta de acceso – Jordan

0

utilizar un carácter diferente y vuelva a colocar el lado del servidor barras

por ejemplo, Drupal.org usa% 21 (el caracter de la marca de exclamación!) Para representar la barra en un parámetro url.

Tanto de los enlaces siguientes trabajos:

https://api.drupal.org/api/drupal/includes%21common.inc/7

https://api.drupal.org/api/drupal/includes!common.inc/7

Si usted está preocupado de que el personaje puede entrar en conflicto con un carácter en el parámetro a continuación, utilizar una combinación de caracteres.

Así que su URL sería http://project_name/browse_by_exam/type/tutor_search/keyword/one_-!two/new_search/1/search_exam/0/search_subject/0

cambio hacia fuera con JS y convertir de nuevo a un lado del servidor barra.

3

tuve el mismo problema con barra de parámetro url conseguir, en mi caso siguiente código PHP funciona:

$value = "hello/world" 
$value = str_replace('/', '/', $value;?> 
$value = urlencode($value);?> 
# $value is now hello%26%2347%3Bworld 

primera vez que se sustituye la barra de entidad html y luego hago la codificación URL.

0

He resuelto mediante el uso de 2 funciones personalizadas de este modo:

function slash_replace($query){ 

    return str_replace('/','_', $query); 
} 

function slash_unreplace($query){ 

    return str_replace('_','/', $query); 
} 

Así que para codificar que podría llamar:

rawurlencode(slash_replace($param)) 

y para decodificar que podría llamar

slash_unreplace(rawurldecode($param); 

Saludos !

0

es simple para mí utilizo base64_encode

$term = base64_encode($term) 
$url = $youurl.'?term='.$term 

después de decodificar el término

$term = base64_decode($['GET']['term']) 

esta manera codificar el "/" y "\"

Cuestiones relacionadas