2012-11-02 11 views

Odpowiedz

69

Z punktu widzenia SEO ten sam link z trailing slash jest inny niż link bez niego. Zaleca się, aby zawsze używać jednego schematu (linków ciągniętych lub nie ciągniętych).

Chociaż istnieją różne szkoły, z których jedna jest lepsza, najważniejsze jest przekierowanie 301 z "niewłaściwego" adresu URL do poprawnego. Możesz to osiągnąć całkiem łatwo w Play z "Dynamic part spanning several /".

Osobiście wolę wersję bez spływu, być może dlatego, że jej implementacja w grze przypomina pisanie kilku prostych linii. Dodaj do swoich tras złożyć tę regułę, gdzieś na początku (zachować ukośnik - to ważne, ponieważ to nie jest uważane za kolejnym cięciem w Spanning-Group, i pozwala dopasować opryskiwacz URL łatwo): wtedy

GET /*path/ controllers.Application.untrail(path: String) 

ty można po prostu zrobić przekierowanie w kontrolerze - do param, więc będzie bez ukośnika na końcu:

Java

public static Result untrail(String path) { 
    return movedPermanently("/" + path); 
} 

Scala

def untrail(path: String) = Action { 
    MovedPermanently("/" + path) 
} 

Do tej pory wszystkie trasy kończące się ukośnikiem zostaną przekierowane do wersji niezamkniętej. Łatwo :)

Oczywiście zdecydowanie zaleca się używanie odwrotnego routera do generowania poprawnych adresów URL - aby zminimalizować zbędne przekierowania. Również, jeśli gdzieś twardo kodujesz adres URL (np. W jakimś JS lub w zewnętrznej aplikacji), lepiej też pisać poprawne, zamiast tego za każdym razem je konwertować. Jeśli planujesz opublikować jakiś publiczny interfejs API, zanotuj w dokumentacji, jaki wzorzec ma Twoja aplikacja, więc programiści zostaną ostrzeżeni i (być może) przygotują poprawne połączenia.

Co więcej - najważniejsze dla tras GET, ponieważ są one przedmiotem manipulacji ze strony klienta. Podczas korzystania z POST, PUT, DELETE i innych nie potrzebujesz (lub raczej nie powinieneś) dbać o przekierowania, ponieważ nie mogą być zmienione przez użytkownika iw ten sposób musisz zapamiętać, w jaki sposób wybierzesz. W przypadku złego połączenia np. w przypadku POST wystarczy zwrócić błąd 404 - więc deweloper trzeciej aplikacji częściowej będzie zobowiązany do używania poprawnych zakończeń.

+0

Bardzo dobra odpowiedź, spróbuję ... – opensas

+1

Dzięki. W Scali wygląda to tak: def untrail (ścieżka: String) = Akcja {MovedNerwalnie ("/% s" .format (ścieżka))} –

+0

@ ChristopherMartin, thanx, skopiowałem twoją próbkę do odpowiedzi – biesior

0

Dodaj pozycję dwukrotnie w pliku trasy. Jeden z ukośnikiem i drugi bez.

+0

cóż, tak, to obejście, które do tej pory znalazłem, staram się tylko utrzymać czyste trasy – opensas

+0

podwojenie to zła rzecz – mmmbell

+0

@ygra Dlaczego dzięki, to było konstruktywne. –

7

udało mi się wymyślić coś, to nie było tak proste, jak miałem nadzieję, ale to nie jest fizyka jądrowa albo

import play.api.mvc.RequestHeader 

import play.api.Play.current 

class NormalizedRequest(request: RequestHeader) extends RequestHeader { 

    val headers = request.headers 
    val queryString = request.queryString 
    val remoteAddress = request.remoteAddress 
    val method = request.method 

    val path = request.path.stripSuffix("/") 
    val uri = path + { 
    if(request.rawQueryString == "") "" 
    else "?" + request.rawQueryString 
    } 
} 

object NormalizedRequest { 
    def apply(request: RequestHeader) = new NormalizedRequest(request) 
} 

ans potem używać go tak jak to w Global.scala

override def onRouteRequest(request: RequestHeader): Option[Handler] = { 
    super.onRouteRequest(NormalizedRequest(request)) 
} 
+2

Przykłady globalnego przechwytywania w praktyce są bardzo nieliczne, +1 dla prawdziwego świata – virtualeyes

1

ta opiera się na opensas's answer, tylko uproszczone trochę do ponownego użycia play wbudowanej copy sposobu na RequestHeader tak, że wszystkie rzeczy w oryginalnym RequestHeader są przechowywane, jak id, tagów, wersja bezpieczna itp

import play.api.GlobalSettings 
import play.api.mvc.{Handler, RequestHeader} 

trait TrailingSlashNormaliser extends GlobalSettings { 

    def removeTrailingSlash(origReq: RequestHeader): RequestHeader = { 
    if (origReq.path.endsWith("/")) { 
     val path = origReq.path.stripSuffix("/") 
     if (origReq.rawQueryString.isEmpty) 
     origReq.copy(path = path, uri = path) 
     else 
     origReq.copy(path = path, uri = path + s"?${origReq.rawQueryString}") 
    } else { 
     origReq 
    } 
    } 

    override def onRouteRequest(request: RequestHeader): Option[Handler] = 
    super.onRouteRequest(removeTrailingSlash(request)) 

} 

/** 
* Global object that removes trailing slashes from requests. 
*/ 
object Global extends TrailingSlashNormaliser 
+1

'if (origReq.path.endsWith ("/") && origReq.path! ="/") {' – radekg

5

Updated przykład przez @opensas i @lloydmeta do zabawy 2,5

/** 
    * HttpRequestHandler that removes trailing slashes from requests. 
    */ 
class TrailingSlashNormaliserHttpRequestHandler(router: Router, errorHandler: HttpErrorHandler, configuration: HttpConfiguration, filters: HttpFilters) extends HttpRequestHandler { 

    private val default = new DefaultHttpRequestHandler(router, errorHandler, configuration, filters) 

    override def handlerForRequest(request: RequestHeader): (RequestHeader, Handler) = { 
    default.handlerForRequest(removeTrailingSlash(request)) 
    } 

    private def removeTrailingSlash(origReq: RequestHeader): RequestHeader = { 
    if (origReq.path.endsWith("/") && origReq.path != "/") { 
     val path = origReq.path.stripSuffix("/") 
     if (origReq.rawQueryString.isEmpty) { 
     origReq.copy(path = path, uri = path) 
     }else { 
     origReq.copy(path = path, uri = path + s"?${origReq.rawQueryString}") 
     } 
    } else { 
     origReq 
    } 
    } 
} 

zobaczyć https://www.playframework.com/documentation/2.5.x/ScalaHttpRequestHandlers instrukcje dotyczące sposobu stosowania obsługi

Powiązane problemy