2012-11-02 14 views

risposta

69

Dal punto di vista SEO lo stesso collegamento con trailing slash è diverso dal collegamento senza di esso. Si consiglia vivamente di utilizzare sempre uno schema (collegamenti trainati o non-trainati).

Sebbene esistano scuole diverse, una delle quali è la più importante è quella di effettuare un reindirizzamento 301 dall'URL "errato" al corretto. Puoi ottenerlo abbastanza facilmente in Play con un 'Dynamic part spanning several /'.

Personalmente preferisco la versione non trascinata, forse perché implementarla nel Play è come scrivere poche righe semplici. Aggiungi ai tuoi percorsi file di questa regola, da qualche parte all'inizio (tenere la barra - è importante in quanto non è considerato come la prossima barra nel spanning-gruppo, e permette di abbinare trainati URL facilmente):

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

allora si può solo fare un reindirizzamento nel controllore - per il parametro, quindi sarà senza la slash alla fine:

Java

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

Scala

Fino ad ora, tutti i percorsi che terminano con la barra verranno reindirizzati alla versione non trascinata. Facile :)

Ovviamente si consiglia vivamente di utilizzare il router inverso per generare URL corretti - per ridurre al minimo i reindirizzamenti ridondanti. Inoltre, se si sta codificando l'URL da qualche parte (ad esempio in alcuni JS o in un'applicazione esterna) è anche meglio scrivere quelli corretti e convertirli ogni volta. Se hai intenzione di pubblicare alcune API pubbliche, fai una nota nella documentazione, quale modello preferisce la tua applicazione, così gli sviluppatori saranno avvisati e (forse) prepareranno le chiamate corrette.

Inoltre, è importantissimo per le route GET in quanto sono soggette alla manipolazione da parte del cliente. Durante l'utilizzo di POST, PUT, DELETE e altri non è necessario (o piuttosto non dovrebbe) preoccuparsi dei reindirizzamenti in quanto non possono essere modificati dall'utente e in questo modo è necessario ricordare in quale modo si sceglie. In caso di chiamata sbagliata vale a dire. per POST, è sufficiente restituire un errore 404, quindi lo sviluppatore dell'applicazione di terze parti sarà obbligato a utilizzare terminazioni corrette.

+0

risposta molto buona, farò un tentativo ... – opensas

+1

Grazie. E in Scala, questo sembra: def untrail (path: String) = Action {MovedPermanently ("/% s" .format (path))} –

+0

@ChristopherMartin, grazie, ho copiato il tuo campione in risposta – biesior

0

Aggiungere la voce due volte nel file di percorso. Uno con la barra e uno senza.

+0

beh, sì, questa è la soluzione che ho trovato finora, sto solo cercando di mantenere puliti i percorsi – opensas

+0

il raddoppio è una cosa negativa – mmmbell

+0

@ygra Perché grazie, è stato costruttivo. –

7

Sono riuscito a tirar fuori qualcosa, non è stato così semplice come speravo, ma è scienza missilistica sia

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 poi lo uso come questo in Global.scala

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

Esempi di intercettazione Globale in pratica sono pochi e distanti tra loro, +1 per un caso del mondo reale – virtualeyes

1

questo si basa su opensas's answer, solo semplificato un po 'di riutilizzare Play built-in copy metodo su RequestHeader in modo che tutte le cose che nell'originale RequestHeader sono tenuti, come id, i tag, versione, sicuro, ecc

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

Aggiornato l'esempio @opensas e @lloydmeta per giocare 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 
    } 
    } 
} 

vedere https://www.playframework.com/documentation/2.5.x/ScalaHttpRequestHandlers per le istruzioni su come applicare il gestore