Angular.js: encodeUriSegment em parâmetros de codificação de recursos, deve ser opcional

Criado em 19 set. 2012  ·  55Comentários  ·  Fonte: angular/angular.js

Ao ter um $resource e enviar um parâmetro para ser usado na url, seria legal se houvesse a opção de não codificá-lo. OOB codifica (neste caso, o parâmetro "path") antes de corresponder ao URL. Por exemplo

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

Isso resultará em uma chamada para url "/game%2Fmygame.json" em vez de "/game/mygame.json".

Há uma solução rápida de correção:

// 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
  }

Eu não tenho idéia do que vai quebrar, mas como sei que funciona para mim. Pode-se também sequestrar o argumento actions em ResourceFactory e passar um sinalizador de codificação de salto para o argumento padrão do construtor de Rota para dizer a ele para ignorar a codificação.

Lots of comments ngResource moderate more info feature

Comentários muito úteis

@ibrahim89 , certifique-se de usar a mesma versão de angular e angular-resource.

Todos 55 comentários

Criei um gist com as mudanças para seqüestro :) https://gist.github.com/3749345

+1 para isso. Proporciona maior flexibilidade. Em nosso caso de uso, estamos usando o spring data rest para o back-end e os métodos de pesquisa são parâmetros de caminho que precisamos mapear para ações, idealmente no mesmo objeto de recurso das operações CRUD básicas.

+1. Nossos ids contêm barras (usamos RavenDB) e seria uma solução limpa se não fosse codificado

Torná-lo opcional é bom, mas certifique-se de que ele esteja ativado por padrão.

É desaconselhável não codificar URIs. Não fazer isso pode parecer "limpo" agora, mas garanto que isso vai te morder na bunda nesta vida ou na próxima.

Se eu ler http://www.ietf.org/rfc/rfc3986.txt corretamente, devemos ter permissão para a barra não codificada para o fragmento.

3.5. Fragmento

O componente identificador de fragmento de um URI permite
identificação de um recurso secundário por referência a um recurso primário
recurso e informações de identificação adicionais. O identificado
recurso secundário pode ser alguma parte ou subconjunto do recurso primário
recurso, alguma visão sobre as representações do recurso primário, ou
algum outro recurso definido ou descrito por essas representações. UMA
componente identificador de fragmento é indicado pela presença de um
caractere de sinal numérico ("#") e encerrado no final do URI.

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

...
Os caracteres barra ("/") e ponto de interrogação ("?")
representam dados dentro do identificador de fragmento. Cuidado que alguns
implementações mais antigas e errôneas podem não manipular esses dados corretamente
quando é usado como URI base para referências relativas (Seção
5.1).

Caso de uso: $location.hash('/secondary-resource')

Estou apenas curioso, é possível evitar esse problema codificando duas vezes seus parâmetros?

Desculpe, então torna ainda pior. Só para confirmar, experimentei várias aberturas, embora parecesse inútil!

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

Além disso,

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

Obrigado pelo pensamento. Pedido ainda está de pé.

Correu para isso hoje. +1
Eu posso não gostar, mas nosso id contém barras também. Isso precisa ser opcional.

+1

+1

+1

+1

+1

+1

Eu vejo menção a um banco de dados (RavenDB) que torna a implementação atual problemática, mas eu esperaria que houvesse um servidor intermediário que esperasse componentes codificados e os decodificasse para o ID correto no back-end. Alguém poderia fornecer um caso de uso mais concreto sobre onde a codificação forçada está causando problemas (desculpe, não tenho mais contexto no RavenDB)?

Hesitamos em permitir isso com o design atual de $resource, porque facilitaria muito a entrada do usuário para afetar o caminho de uma solicitação.

Eu uso $location para um design REST/hipermídia e não RavenDB (ou $resource). Eu tive que trabalhar com uma versão corrigida da biblioteca.

Também estou buscando confirmação de que, de fato, esta proposta também segue a RFC - veja meu comentário acima

Eu também posso estar um pouco enferrujado em torno da biblioteca - grandes desculpas se estiver errado - também existem duas implementações de uma em recurso em L332 e uma em Angular em 1071 .

Eu só preciso daquele em Angular porque é o que é usado por $location ;-) (sim, eu vejo o problema aqui, então não sugiro que não haja implementações diferentes). Peço desculpas se tiver alguma análise incorreta.

+1
Alguém tem uma solução alternativa para a construção de URLs de recursos contendo barras?

De acordo com a linha de patch mencionada acima nos arquivos, as duas implementações também mencionadas acima . É uma dor.

Existe algum movimento sobre isso?
Basta adicionar um ponto em que eu realmente poderia usar essa opção.

ei,

Eu tenho o mesmo problema, mas a essência não faz funcionar para mim. onde devo colocar esse método encodeUirSegment ou onde posso colocar essa opção? :/

Eu estava usando um interceptor HTTP para transformar URLs. Estava funcionando até que eu testei no IE11. Quebras angulares em solicitações XHR para URLs, incluindo % no IE11. Não tenho certeza sobre o IE10. Angular deve suportar IE9+ ( referência )

Acho que vou voltar para o ngResource modificado.

@connorbode --- cara, como foi mencionado no seu problema, escreva um caso de teste com falha =) Este caminho já DEVE estar coberto, então há duas possibilidades, ou não está coberto e deveria estar, ou você está fazendo algo para quebrar isto.

Vamos descobrir qual é!

+1

+1

+1

Impossível trabalhar com CouchDB e documentos de design (_design/cafehub/_view/menu_items)

Vocês podem marcar com +1 meu pull request em vez deste problema? Ele corrige o problema, mas tem sido geralmente ignorado desde a sua apresentação. https://github.com/angular/angular.js/pull/7940

+1
Realmente preciso disso para interagir com alguns webservices legados que não executam URLdecode

+1

Existem circunstâncias definitivamente viáveis ​​e úteis em que um usuário desejará desabilitar a codificação de parâmetros de URL (por exemplo, onde você deseja anexar a uma URL base um caminho para um recurso).

+1

+1

+1

+1

@toddb apenas FYI, sua cotação de especificação refere-se à parte do fragmento de um URL, ou seja, a parte #foo/bar , onde escapar de uma barra não é realmente necessário ou apropriado. Mas esse bug é sobre como escapar de uma barra na parte do caminho principal da URL. Em geral, não acho que o RFC se aplique a isso, como o serviço $resource do Angular lida com correspondência de padrões e construção de URL realmente não preocupa muito o RFC.

Não escapar barras em um parâmetro de estilo :param regular tem o problema de tornar o padrão não inversível. Por exemplo, se você tiver /x/:param e permitir a geração /x/y/z para {param: 'y/z'} , o /x/y/z resultante falhará ao analisar o padrão de URL.

IMHO pode fazer sentido ter um recurso em padrões de URL para aceitar um padrão de estrela que come barras, por exemplo "/:param1/:param2/*pathParam" , onde *pathParam come barras na URL. Para parâmetros * , faria sentido também aceitar barras sem escapar delas.

@mprobst - você está certo de que eu estava registrando um bug apenas em torno do fragmento. O código como eu o uso _também_ afeta o fragmento. Não estou usando o serviço $resource , mas sim $location . Se minha memória não me falha, existem algumas implementações do código uriSegment.

O patch de @connorbode de uma leitura rápida resolverá o problema. Felicidades

+1

+1

+1

+1

+1

+1

+1

+1

Você pode usar a mesma sintaxe como no ui-router lib :
http://angular-ui.github.io/ui-router/site/#/api/ui.router.util.type :UrlMatcher

+1

também acontece no local

:+1:

+1

Estou fazendo uma decodificação para enviar meu URL original para o back-end

.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

estou recebendo este erro no serviço angularjs $ resource
Erro: encodeUriSegment não é uma função

@ibrahim89 , certifique-se de usar a mesma versão de angular e angular-resource.

@gkalpak , obrigado !!

meu erro foi resolvido

Esta página foi útil?
0 / 5 - 0 avaliações