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

$resource strips port from url #1243

Closed
thughes opened this issue Aug 8, 2012 · 36 comments
Closed

$resource strips port from url #1243

thughes opened this issue Aug 8, 2012 · 36 comments

Comments

@thughes
Copy link
Contributor

thughes commented Aug 8, 2012

As discussed in https://groups.google.com/forum/?fromgroups#!topic/angular/18aO0bIlEm0%5B1-25%5D, if you include a port in the URL passed to $resource, it gets stripped since everything with a colon is substituted.

Escaping the colon works, but that makes it a pain to use the same URL with $http (which doesn't seem to understand the escaping).

In general you should be using relative URLs, but the use case for needing the full path is for cross origin requests.

@ProLoser
Copy link
Contributor

ProLoser commented Sep 5, 2012

Is this a bug or... what? Seems redundant to #942

Or are you making a bug asking specifically what @JamesDunne proposed

@thughes
Copy link
Contributor Author

thughes commented Sep 5, 2012

It's supposed to be a bug. It's the same as #942, but that issue was closed with "you need to use escaping". My point here was to illustrate that escaping isn't really a solution (every first time user of angular using a port number will hit it and $http doesn't understand the escaping so you can't use the same URL).

@JamesDunne's proposal seems fine, but I wasn't advocating any particular solution.

@vitch
Copy link

vitch commented Sep 14, 2012

I've just run into this problem too. Additionally, it doesn't seem to work escaping the colon with a backslash (using 1.0.2)

@frapontillo
Copy link
Contributor

The backslash escaping does not work for me; I'm using v1.0.2.

@earlyriser
Copy link

I'm having the same problem: escaping : doesn't work and I'm using 1.0.2

Do you have found any solution?

Trying to access a url of this kind: http://subdomain.domain.com:9000/some/parameters

@frapontillo
Copy link
Contributor

A workaround would be to include a port parameter with a custom fixed value, such as http://subdomain.domain.com:port/some/parameters.

@oilart
Copy link

oilart commented Oct 11, 2012

Hi, that is really confusing problem. To fix that I was using {port} parameter in all resource instances as others do but, code gets really messy. So, I decided to have a single URL address in the configuration and came up with another solution, so try to use this:

$resource('http://localhost:XXXX\:XXXX/api/entities'); 

Test (in Coffeescript)

describe "Resource port replacment test", ->
  entity=null

  beforeEach module("YourApp")
  beforeEach inject(($resource, $httpBackend) ->
    @entity = $resource 'http://localhost:56789\:56789/api/entities'
    @httpBackend = $httpBackend
    @httpBackend.expectGET('http://localhost:56789/api/entities').
          respond(200, '1'))

  afterEach ->
    @httpBackend.verifyNoOutstandingExpectation()
    @httpBackend.verifyNoOutstandingRequest()

  it "checking the address", ->
    @entity.query {}
    @httpBackend.flush()

It's another trick, but works fine for me. Hope you guys can fix it in the next release.

Cheers

@cmdrkeene
Copy link

There is a also a disparity between how $resource and $http handle this.

For example, if you use a common config variable with the double port (http://localhost:3000\:3000) as proposed above:

  • $http requests go to http://localhost:3000:3000
  • $resource requests go to http://localhost:3000

UPDATE: This was mentioned in the original ticket. Sorry for the repost, but it's a major pain for cross-domain and local development.

@xealot
Copy link

xealot commented Oct 30, 2012

Ran into this issue today, was able to solve with the following:

var escapedUrl = window.API_PREFIX.replace(/:([^\/])/, '\\:$1');

(Note: I'm sure that's not the best way to do it)

It seems that a : is a poor use for a string interpolation marker here since the chance of needing to specify hostname in the ajax call is high. Especially with the increasing popularity of projects completely decoupled from their associated API.

While I imagine regressions would make it infeasible to change at this point a much more acceptable token would be something like /api/{userId} which is pretty popular as well and unused in the URL. Colon was most likely chosen because it's a common paradigm in a lot of server-side URL dispatching and routing applications but the character is heavily reserved in URL schemes.

@pkozlowski-opensource
Copy link
Member

You can escape port number using double \\, ex.: http://198.61.201.6\\:8000/api/v1-dev/trackers
Here is the jsFiddle: http://jsfiddle.net/mkLzh/

Docs were updated in c398d7d thnx to @jsyrjala !
On-line docs should be updated soon as well.

@TLmaK0
Copy link

TLmaK0 commented Jan 4, 2013

I think you can provide a better solution. The behaviour is different from $http. This is a workaround and very ugly. You should check "protocol://server:port". Are you really thinking that someone could use :port as variable? There are a lot of people asking for this problem. Don't fix it now, but keep it open please.

@mernen
Copy link
Contributor

mernen commented Jan 29, 2013

How about we disallow :identifiers that start with a digit? This is a pretty common restriction (see identifiers in JS itself, and most programming languages), so I don't think anyone will be caught by surprise. Real-world impact should also be minimal, I assume.

@cmdrkeene
Copy link

👍
On Jan 28, 2013 11:04 PM, "Daniel Luz" notifications@github.com wrote:

How about we disallow :identifiers that start with a digit? This is a
pretty common restriction (see identifiers in JS itself, and most
programming languages), so I don't think anyone will be caught by surprise.
Real-world impact should also be minimal, I assume.


Reply to this email directly or view it on GitHubhttps://github.com//issues/1243#issuecomment-12819649.

jbdeboer pushed a commit to jbdeboer/angular.js that referenced this issue Feb 9, 2013
@nanodeath
Copy link

I'm going to 👍 this issue as this is still a pretty gnarly issue -- definitely bit a first time user like me. The reason I hit it is because I'm doing local development on a Chrome app, so it makes sense that my endpoint would be something like http://localhost:3000, no? Just seems bizarre that I should have to escape the port number. I like @mernen's solution.

@wildlyinaccurate
Copy link

I'd like to 👍 @mernen's solution. This is a real pain in the ass and it requires some kludgey code to get $http and $resource using the same URL.

@karlfreeman
Copy link

Just another 👍 to say I've been hit by this moving between $resource and $http and wondering why things weren't working. Until I realised the port behaviour wasn't the same across them.

@bbonamin
Copy link

Unfortunately the work around isn't feasible if you share URLs between $resource and $http.

We have a subdirectory for the production deployment, so the url needs to change to app.com/subdirectory. What we did to solve this is, instead of injecting a service to all factories that returns the full URL with the port for development, and the URL with the subdirectory for production, we are now just returning '/subdirectory' for production and an empty string for development, and the browser completes the URL path. It works great.

@kdekooter
Copy link

As @bbonamin said, escaping the colon works for for $resource now. But it DOES NOT WORK for $http. So the issue is not fixed! Please reopen the issue and fix it in a way that enables us to use the same url for both. This is really a huge showstopper at dev time.

@pkozlowski-opensource
Copy link
Member

I see that it might be a pain for people sharing the same URL across $http and $resource. @kdekooter I guess you will be motivated to send a pull request if this is a blocking point for you!

@jsyrjala
Copy link
Contributor

jsyrjala commented Jul 6, 2013

@mernen has the best solution: let's change $resource so that patterns in URLs can't start with digit.
I think that the right place to change code is somewhere around here https://github.com/angular/angular.js/blob/master/src/ngResource/resource.js#L347

jsyrjala added a commit to jsyrjala/angular.js that referenced this issue Jul 6, 2013
Currently URLs like http://example.com:8080/some/path
do not work with $resource without tricks because port number
:8080 is handled as path parameter. This commit changes $resource to
ignore parameters that start with a digit. Fixes angular#1243.
@kdekooter
Copy link

@pkozlowski-opensource yes I am motivated! Will try to create a pull request shortly.

@kdekooter
Copy link

I disagree with @mernen and @jsyrjala. I think we should keep the behavior of $http and $resource consistent. It should be quite easy to detect if part of the url can be interpreted as a port number. Anything of the pattern 'colon-numerical value' right after a domain name is a port number. No need to require parameters to start with a letter.

@petebacondarwin
Copy link
Contributor

This is already being addressed in #2778

@kdekooter
Copy link

@petebacondarwin that is exactly what I mean! The question remaining is: will this pull request be honored? And if yes in which release?

@petebacondarwin
Copy link
Contributor

I am pretty confident that it will be merged. Need to get it reviewed.
Not sure if it can be merged into stable branch since it will change the API - but arguably no-one would be relying on the buggy behaviour. Let's move this discussion over to the PR.

@kdekooter
Copy link

OK people, let's all vote for PR #2778!
This issue can be closed once the PR is merged.

@Narretz
Copy link
Contributor

Narretz commented Jul 25, 2013

This can be closed. It has landed in b94ca12

@deitch
Copy link

deitch commented Sep 30, 2013

As of which version does this work? angular-seed still has the old version, see https://github.com/angular/angular-seed/blob/master/app/lib/angular/angular-resource.js#L290

@Narretz
Copy link
Contributor

Narretz commented Sep 30, 2013

the seed app uses angular 1.0.7, an outdated release of the stable branch. This change was introduced in the unstable branch, at 1.2.0rc1. This is part of the unstable branch, which contains quite a few breaking changes. Since it's not a huge change you could apply the commit to the stable branch as a patch.

(If you click on the commit, you can see the releases (tags) and branches that contain this change. And the top of the resource file you linked to contains the version number)

@deitch
Copy link

deitch commented Oct 1, 2013

Yeah, I saw that it was in 1.2.0rc1 on the commit page. Didn't realize seed was outdated; angularjs.org says latest stable is 1.0.8?

Completely separately, since REST is so core to just about every Web API written in the last few years, why isn't ngResource part of the core angular.j/angular.min.js file?

@Narretz
Copy link
Contributor

Narretz commented Oct 1, 2013

Seed is outdated because it uses 1.0.7. 1.2 RC2 is still unstable.
Module separation is actually a good thing. It allows you to pick only the parts you need (My api wrapper uses only $http), and with more and more standardization, in the future you'll be able to mix and match modules. This could soon happen for angular's $http for example.

@deitch
Copy link

deitch commented Oct 1, 2013

1.0.8 is highest stable, right?

I agree on module separation. My question was:

  1. Wouldn't REST interface be considered core enough?
  2. Unlike server-side (think npm), the dependencies are not automatically and clearly defined. Need to know clearly, "resource v1.1.2 works with angular v1.1.8 or lower," etc.
  3. It would really help if there were clear independent versioning of the modules
  4. Are these modules on CDNs? I haven't seen something as core as resource on Google or cdnjs.com

@mernen
Copy link
Contributor

mernen commented Oct 1, 2013

  1. REST support is certainly important, but there's certainly more than one way to do it (say, a more specialized service, doing JSON API or HAL), and there are concerns ngResource isn't solid enough right now.
    (This is the same reason $route was extracted into the ngRoute module; routing is essential to lots of applications, but $route lacked many features deemed important, so it made little sense to drag those who were using alternative routers down with unused services)
  2. Right now the rule is just "angular-XX v1.0.8 works with angular v1.0.8, nothing else is guaranteed"
  3. The rule I just described helps in keeping things simple, but this is certainly the downside here. Perhaps as Angular matures this will improve.
  4. Yes, all the angular-* modules that are part of the official distribution are on Google's CDN. But indeed, I don't see any clear indication of that on the home page. Just checked CDNJS, and the modules are there too (latest 1.1 releases are lacking, but 1.0.x seems complete).

@deitch
Copy link

deitch commented Oct 1, 2013

  1. REST support is certainly important, but there's certainly more than one way to do it (say, a more specialized service, doing JSON API or HAL), and there are concerns ngResource isn't solid enough right now.

I can see that, but I think you can get 80% of use cases with a basic version and config opts.

(This is the same reason $route was extracted into the ngRoute module; routing is essential to lots of applications, but $route lacked many features deemed important, so it made little sense to drag those who were using alternative routers down with unused services)

But isn't ngRoute still part of angular.js? I don't need to include any other file to get it.

  1. Yes, all the angular-* modules that are part of the official distribution are on Google's CDN. But indeed, I don't see any clear indication of that on the home page. Just checked CDNJS, and the modules are there too (latest 1.1 releases are lacking, but 1.0.x seems complete).

Huh! It wasn't listed as on the Google site, but it is if you manually change the URL to do angular-resource.js or angular-resource.min.js. Same for cdnjs. You can even search on cdnjs, but it is not listed. Very helpful, thank you.

@xealot
Copy link

xealot commented Oct 1, 2013

We are unable to use angular's REST support directly, our project fits in that use case.

@deitch
Copy link

deitch commented Oct 1, 2013

I am sure many do. But I think REST in its basic forms cover so many use cases, and angular-resource is 2.7KB minified, 1.4KB gzipped, I can see it being core.

But I am just a fairly new user (to Angular anyways) expressing an opinion. :-)

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

Successfully merging a pull request may close this issue.