Der nachfolgende Schrägstrich löst 404 in der Flaschenpfadregel aus

76

Ich möchte jeden Pfad unter /userszu einer statischen App umleiten . Die folgende Ansicht sollte diese Pfade erfassen und die entsprechende Datei bereitstellen (sie druckt nur den Pfad für dieses Beispiel). Dies funktioniert für /users, /users/604511und /users/604511/action. Warum /users/verursacht der Pfad einen 404-Fehler?

@bp.route('/users')
@bp.route('/users/<path:path>')
def serve_client_app(path=None):
    return path
Jesvin Jose
quelle

Antworten:

132

Ihrer /usersRoute fehlt ein abschließender Schrägstrich, den Werkzeug als explizite Regel interpretiert, um nicht mit einem abschließenden Schrägstrich übereinzustimmen. Fügen Sie entweder den abschließenden Schrägstrich hinzu, und Werkzeug leitet um, wenn die URL ihn nicht enthält, oder setzen Sie strict_slashes=Falsedie Route, und Werkzeug entspricht der Regel mit oder ohne Schrägstrich.

@app.route('/users/')
@app.route('/users/<path:path>')
def users(path=None):
    return str(path)

c = app.test_client()
print(c.get('/users'))  # 302 MOVED PERMANENTLY (to /users/)
print(c.get('/users/'))  # 200 OK
print(c.get('/users/test'))  # 200 OK
@app.route('/users', strict_slashes=False)
@app.route('/users/<path:path>')
def users(path=None):
    return str(path)

c = app.test_client()
print(c.get('/users'))  # 200 OK
print(c.get('/users/'))  # 200 OK
print(c.get('/users/test'))  # 200 OK

Sie können auch strict_slashesfür alle URLs festlegen .

app.url_map.strict_slashes = False

In den meisten Fällen sollten Sie jedoch vermeiden, strenge Schrägstriche zu deaktivieren. Die Dokumente erklären, warum:

Durch dieses Verhalten können relative URLs auch dann weiterarbeiten, wenn der abschließende Schrägstrich weggelassen wird. Dies entspricht der Funktionsweise von Apache und anderen Servern. Außerdem bleiben die URLs eindeutig, wodurch Suchmaschinen vermeiden, dieselbe Seite zweimal zu indizieren.

Davidismus
quelle
45

Strenge Schrägstriche GLOBAL deaktivieren; Set url_map.strict_slashes = Falseso:

app = Flask(__name__)
app.url_map.strict_slashes = False

Auf diese Weise müssen Sie nicht strict_slashes=Falsefür jede Ansicht verwenden.

Dann definieren Sie einfach die Route ohne einen abschließenden Schrägstrich wie folgt:

bp = Blueprint('api', __name__, url_prefix='/api')
@bp.route('/my-route', methods=['POST'])

Dann /my-routeund /my-route/beide arbeiten identisch.

Nick Woodhams
quelle
Wie würden wir strenge Schrägstriche für Blaupausen machen, ohne sie für jede Ansicht zu definieren?
jchi2241
@ jchi2241 Verpasste Ihren Kommentar für ein Jahr - Entschuldigung. Das Beispiel verwendet Blaupausen, die Sie auf App-Ebene konfigurieren.
Nick Woodhams
15

Dies liegt an der Konsistenz von Werkzeug mit anderen HTTP-Servern. Schauen Sie sich die Quickstart-Dokumentation von Flask an . Der relevante Absatz:

Eindeutige URLs / Umleitungsverhalten

Die URL-Regeln von Flask basieren auf dem Routing-Modul von Werkzeug. Die Idee hinter diesem Modul ist es, schöne und eindeutige URLs sicherzustellen, die auf Präzedenzfällen basieren, die von Apache und früheren HTTP-Servern festgelegt wurden.

Nehmen Sie diese beiden Regeln:

@app.route('/projects/') 
def projects():
    return 'The project page'

@app.route('/about') 
def about():
    return 'The about page'

Obwohl sie ziemlich ähnlich aussehen, unterscheiden sie sich in der Verwendung des abschließenden Schrägstrichs in der URL-Definition. Im ersten Fall weist die kanonische URL für den Projektendpunkt einen abschließenden Schrägstrich auf. In diesem Sinne ähnelt es einem Ordner in einem Dateisystem. Wenn Sie ohne abschließenden Schrägstrich darauf zugreifen, wird Flask mit dem abschließenden Schrägstrich zur kanonischen URL umgeleitet.

Im zweiten Fall wird die URL jedoch ohne einen abschließenden Schrägstrich definiert, ähnlich wie der Pfadname einer Datei auf UNIX-ähnlichen Systemen. Der Zugriff auf die URL mit einem abschließenden Schrägstrich führt zu einem 404-Fehler "Nicht gefunden".

Durch dieses Verhalten können relative URLs auch dann weiterarbeiten, wenn der abschließende Schrägstrich weggelassen wird. Dies entspricht der Funktionsweise von Apache und anderen Servern. Außerdem bleiben die URLs eindeutig, wodurch Suchmaschinen vermeiden, dieselbe Seite zweimal zu indizieren.

Fügen Sie also einfach /users/auch das Routing hinzu.

Dauros
quelle