Caracterele chirilice în regulile de rescriere generează erori 404 Not Found

20 ian. 2016, 17:46:18
Vizualizări: 958
Voturi: 3

Am o regulă de rescriere care include URI-ul unei pagini:

(<page-uri>)/someaction/(\d+)

Dacă URI-ul paginii conține caractere chirilice, cum ar fi доска-объявлений, regula este stocată ca:

(%d0%b4%d0%be%d1%81%d0%ba%d0%b0-%d0%be%d0%b1%d1%8a%d1%8f%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b9)/someaction/(\d+)

Dacă accesezi o pagină care conține un link către un URL care se potrivește cu regula și dai click pe link, browserul va încărca pagina țintă fără probleme și WordPress reușește să potrivească regula cu URL-ul solicitat.

În Safari (Mac), totuși, dacă copiezi URL-ul cu Click Dreapta > Copiază Link și apoi încerci să încarci pagina țintă lipind URL-ul copiat într-un tab nou, vei primi o eroare 404 Not Found.

Când copiezi URL-ul în Safari, URL-ul este stocat cu codare procentuală, folosind caracterele care reprezintă octeții pentru caracterele chirilice scrise cu majuscule:

%D0%B4%D0%BE%D1%81%D0%BA%D0%B0-%D0%BE%D0%B1%D1%8A%D1%8F%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B9/someaction/1

Nu am reușit să reproduc problema în Chrome sau Firefox (ambele pe Mac) deoarece acestea stochează URL-ul folosind caractere mici pentru a reprezenta octeții.

Acel URL cu codare procentuală este ceea ce primește WordPress prin variabila $_SERVER['REQUEST_URI']. Problema este că codul responsabil pentru potrivirea URI-ului solicitat cu regulile de rescriere face o comparație care ține cont de majuscule/minuscule (Vezi metoda parse_request din /wp-includes/class-wp.php), făcând imposibil ca WordPress să identifice regula mea, chiar dacă

%D0%B4%D0%BE%D1%81%D0%BA%D0%B0-%D0%BE%D0%B1%D1%8A%D1%8F%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B9

și

%d0%b4%d0%be%d1%81%d0%ba%d0%b0-%d0%be%d0%b1%d1%8a%d1%8f%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b9

reprezintă aceeași secvență de caractere.

  • Știe cineva cum să previn erorile 404 Not Found când browserele trimit cererea folosind octeți cu un caz diferit?
  • Este ceva ce WordPress ar trebui să suporte? Sau ar trebui să încerc să elimin URI-urile paginilor din regulile mele de rescriere pentru a evita problema?
3
Comentarii

Și dacă convertesc eu manual доска-объявлений în URI, și apoi adaug mai întâi regula pentru litere mici, iar apoi convertesc același URI în litere mari și adaug regula din nou?

Kolya Korobochkin Kolya Korobochkin
21 ian. 2016 01:59:21
Toate răspunsurile la întrebare 1
0

Am urmat sfatul lui @Kolya Korobochkin și am adăugat versiuni cu majuscule și minuscule ale regulilor de rescriere care includ octeți escapați.

$regular_page_uri = get_page_uri( $page->ID );

$uppercase_page_uri = preg_replace_callback(
    '/%[0-9a-zA-Z]{2}/',
    create_function( '$x', 'return strtoupper( $x[0] );' ),
    $regular_page_uri
);

Plugin-ul Percent Encode Capital Letter utilizează o abordare similară pentru a converti octeții din fiecare URL în versiunea lor cu majuscule. Cu toate acestea, plugin-ul este învechit și poate să nu facă conversia în toate locurile necesare. De asemenea, cred că majoritatea utilizatorilor plugin-ului la care lucrez eu nu vor avea URL-uri cu octeți codificați, așa că rularea preg_replace_callback pentru toate URL-urile este un efort inutil.

Folosirea caracterelor majuscule pentru a reprezenta octeți este metoda recomandată pentru codificarea procentuală (vezi RFC3986, Secțiunea 2.1). Așadar, o soluție mai bună ar fi ca WordPress să actualizeze funcția lor utf8_uri_encode pentru a escapa octeții folosind majusculele. Majoritatea browserelor pe care le-am testat păstrează cazul original, în timp ce altele, cum ar fi Safari, îl convertesc în majuscule, dacă au ocazia.

22 ian. 2016 18:56:13