Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

encodeUriSegment in resource encodes params, should be optional #1388

Open
fredrikbonander opened this issue Sep 19, 2012 · 56 comments · May be fixed by #7940
Open

encodeUriSegment in resource encodes params, should be optional #1388

fredrikbonander opened this issue Sep 19, 2012 · 56 comments · May be fixed by #7940

Comments

@fredrikbonander
Copy link
Contributor

When having a $resource and sending a param to be used in the url, it would be nice if there was an option not to encode it. OOB it encodes (in this case the "path") param before it's match agains the url. For example

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

This will result in a call to url "/game%2Fmygame.json" instead of "/game/mygame.json".

There's a quick-fix-workaround:

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

I have no idea what will break, but as of know it works for me. One could also hijack the actions argument in ResourceFactory and pass a skip encode flag to the Route constructor's defaults argument to tell it to skip the encoding.

@fredrikbonander
Copy link
Contributor Author

Created a gist with the changes for hijacking :) https://gist.github.com/3749345

@manuelsantillan
Copy link

+1 to this. Provides greater flexibility. In our use case, we are using spring data rest for the backend and search methods are path params that we need to map to actions, ideally in the same resource object as for the basic CRUD ops.

@georgiosd
Copy link

+1. Our ids contain slashes (we use RavenDB) and it would be a clean solution if it wasn't encoded

@saden1
Copy link

saden1 commented Apr 1, 2013

Making it optional is fine but please insure that it's enabled by default.

It is ill advised to not encode URIs. Not doing so might seem "clean" now but I assure you it will bite you in the ass in this life or the next.

@toddb
Copy link

toddb commented Apr 26, 2013

If I read http://www.ietf.org/rfc/rfc3986.txt correctly, we should be allowed the unencoded slash for the fragment.

3.5. Fragment

The fragment identifier component of a URI allows indirect
identification of a secondary resource by reference to a primary
resource and additional identifying information. The identified
secondary resource may be some portion or subset of the primary
resource, some view on representations of the primary resource, or
some other resource defined or described by those representations. A
fragment identifier component is indicated by the presence of a
number sign ("#") character and terminated by the end of the URI.

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

...
The characters slash ("/") and question mark ("?") are allowed to
represent data within the fragment identifier. Beware that some
older, erroneous implementations may not handle this data correctly
when it is used as the base URI for relative references (Section
5.1).

Use case: $location.hash('/secondary-resource')

@ProLoser
Copy link
Contributor

I'm just curious, is it possible to avoid this issue by double-encoding your params?

@toddb
Copy link

toddb commented May 11, 2013

Sorry, it then makes it even worse. Just to confirm I tried out a number of opens even though it felt futile!

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

Also,

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

Thanks for the thought. Request still stands.

@sephie
Copy link

sephie commented Jul 10, 2013

Ran into this today. +1
I might not like it, but our id's contain slashes as well. This needs to be optional.

@stevermeister
Copy link
Contributor

+1

5 similar comments
@retailpoint
Copy link

+1

@chelexey
Copy link

+1

@mrzepinski
Copy link

+1

@e0ipso
Copy link

e0ipso commented Dec 3, 2013

+1

@jchonde
Copy link

jchonde commented Jan 28, 2014

+1

@jeffbcross jeffbcross self-assigned this Feb 6, 2014
@jeffbcross
Copy link
Contributor

I see mention of a database (RavenDB) that makes the current implementation problematic, but I'd expect there to be an intermediary server that expects encoded components, and decodes them to the correct ID on the backend. Could someone provide a more concrete use case on where forced encoding is causing problems (sorry I don't have more context on RavenDB)?

We hesitate to allow this with the current design of $resource, because it'd make it to easy for user input to affect the path of a request.

@jeffbcross jeffbcross added this to the Purgatory milestone Feb 6, 2014
@jeffbcross jeffbcross removed their assignment Feb 6, 2014
@toddb
Copy link

toddb commented Feb 6, 2014

I use $location for a REST/hypermedia design and not RavenDB (or $resource). I have had to work with a patched version of the library.

I am also seeking confirmation that in fact this proposal does actually follow the RFC too -see my comment above

I might also be a bit rusty around the library - so big apologies if I am wrong - there are also two implementations of one in resource at L332 and one in Angular at 1071.

I just need the one in Angular because it is what is used by $location ;-) (yes, I see the problem here so I wouldn't suggest haven't different implementations). Apologies if I have any incorrect analysis.

@davecap
Copy link

davecap commented Feb 13, 2014

+1
Anybody have a workaround for constructing resource URLs containing forward slashes?

@toddb
Copy link

toddb commented Feb 13, 2014

As per the patch line mentioned above in the files the two implementations also mentioned above. It's a pain.

@LFDM
Copy link

LFDM commented May 15, 2014

Is there any movement on this?
Just add a point where I could really use such an option myself.

@patricklehmann
Copy link

hey there,

i've the same problem but the gist doesn't make it work for me. where do i have to place this encodeUirSegment method or where can i place this option? :/

@connorbode
Copy link

I was using an HTTP interceptor to transform URLs. It was working until I tested on IE11. Angular breaks on XHR requests to URLs including % in IE11. Not sure about IE10. Angular is supposed to support IE9+ (reference)

Guess I'm going back to the modified ngResource..

@caitp
Copy link
Contributor

caitp commented Jun 17, 2014

@connorbode --- dude, like it was mentioned in your issue, write a failing test case =) This path SHOULD already be covered, so there's two possibilities, either it's not covered and should be, or you're doing something to break this.

Lets find out which it is!

connorbode added a commit to connorbode/angular.js that referenced this issue Jun 23, 2014
@connorbode connorbode linked a pull request Jun 23, 2014 that will close this issue
@adamhadani
Copy link

+1

2 similar comments
@nmehta6
Copy link

nmehta6 commented May 8, 2015

+1

@paulistoan
Copy link

+1

@strokyl
Copy link

strokyl commented Jul 7, 2015

+1

4 similar comments
@kinoakter
Copy link

+1

@tonycapone
Copy link

+1

@jkremser
Copy link

+1

@pavolloffay
Copy link

+1

@patou
Copy link

patou commented Sep 6, 2015

You can use the same syntaxe like in the ui-router lib :
http://angular-ui.github.io/ui-router/site/#/api/ui.router.util.type:UrlMatcher

@jiananshi
Copy link

+1

it also happens in location

@DaAwesomeP
Copy link

👍

1 similar comment
@TheSameSon
Copy link

+1

@jiananshi
Copy link

I'm current doing a decode in order to send my original url to backend

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

@tekstrand
Copy link

+1

1 similar comment
@kishorekumaru
Copy link

+1

@zapolnoch
Copy link

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

#5560

@hadirsa
Copy link

hadirsa commented Aug 12, 2016

+1

@ibrahim89
Copy link

i'm getting this error in angularjs $resource service
Error: encodeUriSegment is not a function

@gkalpak
Copy link
Member

gkalpak commented Oct 22, 2016

@ibrahim89, make sure you use the same version of angular and angular-resource.

@skarensmoll
Copy link

skarensmoll commented Dec 9, 2016

@gkalpak, thank you !!

@ibrahim89
Copy link

my error is solved

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.