Angular.js: encodeUriSegment dans la ressource encode les paramètres, devrait être facultatif

Créé le 19 sept. 2012  ·  55Commentaires  ·  Source: angular/angular.js

Lorsque vous avez une ressource $ et que vous envoyez un paramètre à utiliser dans l'URL, ce serait bien s'il y avait une option pour ne pas l'encoder. OOB il encode (dans ce cas le "chemin") le paramètre avant qu'il ne corresponde à l'url. Par example

// In SomeResourceName factory:
$resouce('/:path',  { path: 'default.json' }, ...)
// Useing SomeResourceName
SomeResourceName.get({ path: 'game/mygame.json' })

Cela se traduira par un appel à l'url "/game%2Fmygame.json" au lieu de "/game/mygame.json".

Il existe une solution rapide :

// In angular-resource.js and method encodeUriSegment
  function encodeUriSegment(val) {
    return encodeUriQuery(val, true).
      replace(/%26/gi, '&').
      replace(/%3D/gi, '=').
      replace(/%2B/gi, '+'). 
      replace(/%2F/gi, '/'); // <--- Add this line
  }

Je n'ai aucune idée de ce qui va casser, mais à ce jour, cela fonctionne pour moi. On pourrait également détourner l'argument actions dans ResourceFactory et passer un indicateur de saut d'encodage à l'argument par défaut du constructeur Route pour lui dire d'ignorer l'encodage.

Lots of comments ngResource moderate more info feature

Commentaire le plus utile

@ ibrahim89 , assurez-vous d'utiliser la même version de angular et angular-resource.

Tous les 55 commentaires

Création d'un essentiel avec les modifications pour le piratage :) https://gist.github.com/3749345

+1 à ça. Offre une plus grande flexibilité. Dans notre cas d'utilisation, nous utilisons Spring Data Rest pour le backend et les méthodes de recherche sont des paramètres de chemin que nous devons mapper aux actions, idéalement dans le même objet de ressource que pour les opérations CRUD de base.

+1. Nos identifiants contiennent des barres obliques (nous utilisons RavenDB) et ce serait une solution propre s'il n'était pas encodé

Le rendre facultatif est acceptable, mais assurez-vous qu'il est activé par défaut.

Il est déconseillé de ne pas coder les URI. Ne pas le faire peut sembler "propre" maintenant, mais je vous assure que cela vous mordra au cul dans cette vie ou dans la suivante.

Si je lis correctement http://www.ietf.org/rfc/rfc3986.txt , nous devrions être autorisés à utiliser la barre oblique non codée pour le fragment.

3.5. Fragment

Le composant d'identificateur de fragment d'un URI permet une
identification d'une ressource secondaire par référence à une ressource primaire
ressource et des informations d'identification supplémentaires. L'identifié
ressource secondaire peut être une partie ou un sous-ensemble de la ressource primaire
ressource, un point de vue sur les représentations de la ressource primaire, ou
une autre ressource définie ou décrite par ces représentations. UNE
composant d'identification de fragment est indiqué par la présence d'un
caractère dièse ("#") et terminé par la fin de l'URI.

 fragment    = *( pchar / "/" / "?" )

...
Les caractères barre oblique ("/") et point d'interrogation ("?") sont autorisés à
représentent les données dans l'identificateur de fragment. Méfiez-vous que certains
les anciennes implémentations erronées peuvent ne pas gérer ces données correctement
lorsqu'il est utilisé comme URI de base pour les références relatives (Section
5.1).

Cas d'utilisation : $location.hash('/secondary-resource')

Je suis juste curieux, est-il possible d'éviter ce problème en encodant deux fois vos paramètres ?

Désolé, cela rend les choses encore pires. Juste pour confirmer, j'ai essayé un certain nombre d'ouvertures même si cela semblait futile!

'/', '%252F' --> %25252F

Aussi,

/ %2f --> %252F
'/', '//' --> %2F%2F

Merci pour la pensée. La demande tient toujours.

J'ai couru dans ça aujourd'hui. +1
Je n'aime peut-être pas ça, mais nos identifiants contiennent aussi des barres obliques. Cela doit être facultatif.

+1

+1

+1

+1

+1

+1

Je vois la mention d'une base de données (RavenDB) qui rend l'implémentation actuelle problématique, mais je m'attendrais à ce qu'il y ait un serveur intermédiaire qui attend des composants codés et les décode avec l'ID correct sur le backend. Quelqu'un pourrait-il fournir un cas d'utilisation plus concret où l'encodage forcé cause des problèmes (désolé, je n'ai pas plus de contexte sur RavenDB) ?

Nous hésitons à autoriser cela avec la conception actuelle de $resource, car il serait plus facile pour l'entrée de l'utilisateur d'affecter le chemin d'une requête.

J'utilise $location pour une conception REST/hypermédia et non RavenDB (ou $resource). J'ai dû travailler avec une version corrigée de la bibliothèque.

Je cherche également à confirmer qu'en fait cette proposition suit également la RFC - voir mon commentaire ci-dessus

Je suis peut-être aussi un peu rouillé autour de la bibliothèque - donc toutes mes excuses si je me trompe - il y a aussi deux implémentations d'une en ressource à L332 et d'une en Angular à 1071 .

J'ai juste besoin de celui dans Angular car c'est ce qui est utilisé par $location ;-) (oui, je vois le problème ici donc je ne suggérerais pas qu'il n'y ait pas d'implémentations différentes). Toutes mes excuses si j'ai une mauvaise analyse.

+1
Quelqu'un a-t-il une solution de contournement pour créer des URL de ressources contenant des barres obliques ?

Selon la ligne de correctif mentionnée ci- dessus dans les fichiers, les deux implémentations sont également mentionnées ci- dessus . C'est une douleur.

Y a-t-il du mouvement à ce sujet?
Ajoutez juste un point où je pourrais vraiment utiliser une telle option moi-même.

salut,

J'ai le même problème mais l'essentiel ne le fait pas fonctionner pour moi. où dois-je placer cette méthode encodeUirSegment ou où puis-je placer cette option ? :/

J'utilisais un intercepteur HTTP pour transformer les URL. Cela fonctionnait jusqu'à ce que je teste sur IE11. Pauses angulaires sur les requêtes XHR aux URL, y compris % dans IE11. Pas sûr pour IE10. Angular est censé supporter IE9+ ( référence )

Je suppose que je reviens au ngResource modifié.

@connorbode --- mec, comme cela a été mentionné dans votre problème, écrivez un cas de test défaillant =) Ce chemin DEVRAIT déjà être couvert, il y a donc deux possibilités, soit il n'est pas couvert et devrait l'être, soit vous faites quelque chose pour casser cette.

Découvrons de qui il s'agit !

+1

+1

+1

Impossible de travailler avec CouchDB et les documents de conception (_design/cafehub/_view/menu_items)

Pouvez-vous +1 ma demande d'extraction au lieu de ce problème ? Il corrige le problème mais a été généralement ignoré depuis sa soumission. https://github.com/angular/angular.js/pull/7940

+1
Vraiment besoin de cela pour interagir avec certains services Web hérités qui n'effectuent pas de décodage d'URL

+1

Il existe certainement des circonstances viables et utiles dans lesquelles un utilisateur voudra désactiver l'encodage des paramètres d'URL (par exemple, lorsque vous souhaitez ajouter à une URL de base un chemin vers une ressource).

+1

+1

+1

+1

@toddb juste pour info, votre citation de spécification fait référence à la partie fragment d'une URL, c'est-à-dire la partie #foo/bar , où échapper une barre oblique n'est en effet ni nécessaire ni approprié. Mais ce bogue consiste à échapper une barre oblique dans la partie chemin principal de l'URL. En général, je ne pense pas que la RFC s'applique à cela, la façon dont le service $resource d'Angular gère la correspondance des modèles et la construction d'URL ne concerne vraiment pas beaucoup la RFC.

Ne pas échapper les barres obliques dans un paramètre de style :param normal a le problème de rendre le motif non inversible. Par exemple, si vous avez /x/:param et que vous autorisez la génération /x/y/z pour {param: 'y/z'} , le /x/y/z résultant ne pourra pas être analysé par rapport au modèle d'URL.

À mon humble avis, il pourrait être judicieux d'avoir une fonctionnalité dans les modèles d'URL pour accepter un modèle en étoile qui mange des barres obliques, par exemple "/:param1/:param2/*pathParam" , où *pathParam mangerait des barres obliques dans l'URL. Pour les paramètres * , il serait alors logique d'accepter également les barres obliques sans les échapper.

@mprobst - vous avez tout à fait raison de dire que je n'enregistrais un bogue qu'autour du fragment. Le code tel que je l'utilise _également_ affecte le fragment. Je n'utilise pas le service $resource mais plutôt $location . Si ma mémoire est bonne, il existe quelques implémentations du code uriSegment.

Le correctif de @connorbode à partir d'une lecture rapide résoudra le problème. Acclamations

+1

+1

+1

+1

+1

+1

+1

+1

Vous pouvez utiliser la même syntaxe que dans la bibliothèque ui-router :
http://angular-ui.github.io/ui-router/site/#/api/ui.router.util.type : UrlMatcher

+1

ça arrive aussi à l'endroit

:+1:

+1

Je suis en train de faire un décodage afin d'envoyer mon URL d'origine au backend

.factory('decodeUriSegment', () => {
    return (url) => {
      return url.replace(/@/g, '%40')
        .replace(/:/g, '%3A')
        .replace(/\$/g, '%24')
        .replace(/,/g, '%2C')
        .replace(/\+/g, '%20');
    };
  });

+1

+1

app.config(function($resourceProvider) {
    $resourceProvider.defaults.stripTrailingSlashes = false;
});

https://github.com/angular/angular.js/pull/5560

+1

je reçois cette erreur dans angularjs $resource service
Erreur : encodeUriSegment n'est pas une fonction

@ ibrahim89 , assurez-vous d'utiliser la même version de angular et angular-resource.

@gkalpak , merci !!

mon erreur est résolue

Cette page vous a été utile?
0 / 5 - 0 notes