-
Notifications
You must be signed in to change notification settings - Fork 27.5k
$resource POST removing trailing slash #992
Comments
Pull request on this issue: https://github.com/angular/angular.js/pull/1064/files |
we just ran into this with django, it was a bit of a tussel, with angular stripping off the slash and django (by default) was adding slash it back end and doing a redirect. Even after changing django default, I ran into an inconsistency with django-tastypie and ended up modifying ngResource to append a slash to make all parties happy. a little differen than fastreload's return url + "/" + (query.length ? '?' + query.join('&') : ''); I think maybe an param option might be nice. --thx dan |
I have done a quick hack on the issue but what I think is that frameworks should treat urls as is. Adding or removing a character from url actually means creating a completely new url and hoping that server will understand what we want. |
I think the convenience of providing the hash with bind elements (as opposed to having a url template), means, that angular needs to muck with the url. I think they tried to cover too many cases and instead should probably just tell the user. What the url will look like in the various cases or provide options to dictate what should happen. IMHO |
Yes, but they could also make their internal interpretation of the urls and use the original url while contacting server. I have not examined the inner workings of url interpretation and routing yet this still does not legitimize changing urls without explicit order from user/coder. Each server can have different types of interpretation urls and a client side framework should be able to communicate with them with no hassle or source changing. For example, Django has |
I think these are great points to bring up. Don't know if you saw but there was a fairly long thread (a number of months ago) on ngResource rewrite and request from comments from Misko. Given the diverse response, I he decided to table things until future time. |
I haven't seen that thread, I am also not using angularjs for that long time, yet the claims that I have said are not design philosophies which is not related to a particular framework (as you said). Hopefully developers will see this issue and change their designs until new development cycle. |
Is there any more discussion on this? It would seem strange that the framework would enforce a certain type of url. |
Not that I know. No active developers have responded to this issue yet. I think that they would agree to that it is wrong to enforce a certain type of url but this part of the framework ( |
There are many deficiencies in $resource. We are trying to figure out what On Tue, Aug 21, 2012 at 4:20 AM, Umur Kontacı notifications@github.comwrote:
|
That would be a proper workaround meanwhile. Thanks for the heads up |
Thanks for the responses! Sorry to ask this here, but following the example, Book is undefined for me in my controller. Any suggestions? |
@stryderjzw the factory is missing return Book, I updated the SE. |
As part of our effort to clean out old issues, this issue is being automatically closed since it has been inactivite for over two months. Please try the newest versions of Angular ( Thanks! |
Hi. This issue still persists in 1.0.8. I'm using $resource to get content from a third-party that needs the URLs to have a trailing slash, and all the requests are being made without the slash. Can we reopen this issue? |
I'll just add this is also a problem in 1.2.0 rcs. This causes problems with many backends that require a trailing slash at the end of requests, |
This is a big problem when using a django backend, which uses URLs with slashes by default. In most cases it responds with a redirect to an URL with trailing slash (which is OK, aside from slowing down the app a bit), but it's impossible when we're sending POST data (and that's a real problem). |
Is there a reason for $resource not respecting the trailing slash? As reported above this is a real issue with Django's POST handling as the server just responds 301 Moved Permanently for a request missing the slash. |
We resorted to use a forked version of angular.js/src/ngResource/resource.js Line 375 in 6a8edc1
|
@btford Can we get an explanation from a core dev regarding this? It's a lingering and festering issue that boils down to one line. I can't find any real reason for it and it's quite obviously a problem for multiple people. It shouldn't really be necessary for me to go use Restangular or drop down to $http just because of this one thing, IMO. Thanks! |
To be clear, while Django users may be the most visible developers encountering this, unless there's a good reason, $resource should not be changing URLs. A slash is often important to a server. |
@ivancamilov It's not really worth creating a pull request; our change is dead simple, any core developer could apply it in a second. This might be more of a political issue than time-related. |
It would indeed be nice to get some clarifying to why striping occurs, is it because of the parameter passing to the URL builder? At least supply user an option to turn it off in the module. |
|
@mpaolini Maybe I'm wrong, but adding space at the end breaks query with parameters (angularjs 1.2.0 rc3): with space: qqApp.factory('Dialing', ['$resource', ($resource) ->
return $resource('/qq/dialing/:dialingId/ ') #space
])
Dialing.query({org: org.id}) # ---> GET /qq/dialing/%20?org=1038 - incorrect
dialing.$save() # ---> POST /qq/dialing/ - correct without space: qqApp.factory('Dialing', ['$resource', ($resource) ->
return $resource('/qq/dialing/:dialingId/') # without space
])
Dialing.query({org: org.id}) # ---> GET /qq/dialing/?org=1038 - correct
dialing.$save() # ---> POST /qq/dialing - problem for me |
@telminov you are right, in the end I had to remove all trailing slashes in my django urlconf and also set |
RC3 still has this issue and it would be awesome if ngResource respected the exact URL it is provided. |
@Cinamonas well, they obviously won't change that for 1.2.0 as it's a breaking change and a lot of code could break because of that. Too late for that now. |
@mzgol Adding an option for opt-out wouldn't break anything. |
@mik01aj Ah, that's true. But it won't make it to 1.2.0 anyway, they're not accepting new features now. |
@mzgol - I went ahead with the approach you mentioned in your earlier comment (ie. commenting out the line where the trailing slash gets stripped). You also mentioned that a lot of code could break because of that. I couldn't think of any cases that this change would break anything. Could you please enlighten me with a few examples? Thanks. |
@tamakisquare That's simple, any code that would pass URLs with trailing slashes in some places and without in the others would break if the normalization process would be turned on. '$resource' will either have to be changed in a non-patch version bump or via adding an option to disable normalization but not by default. |
Please add the option to disable normalization. |
+1 for adding an option. This seems too dumb an issue to keep. FWIW you can hack the behavior via double escaping the trailing slash, like: |
@casio thanks for the tip - I just ran into this issue with a Flask backend. |
@casio Thanks for that tip. This workaround seems to break in Firefox, though. |
As @nvie has indicated the workaround by @casio does not work in firefox, |
I took a different approach to remedy this incompatibility issue with my django backend. Just thought to share with the folks encountering the same problem for the time being. I wrote a custom response interceptor that adds the trailing slash if the url doesn't already have one. Note that the interceptor skips the requests that are configured to use $http cache. |
I think the best fix is adding |
That sometimes isn't an option. The best fix would be having this be configurable in the
Where
When the |
This problem isn't just for Django people. We have a custom PHP webservice that was created with all trailing slashes. |
My pull request to attempt to fix this for once and for all is #5560. This should support the following configuration: app.config(function($resourceProvider) {
$resourceProvider.defaults.stripTrailingSlashes = false;
}); or per instance, using a new, fourth, optional argument to the var CreditCard = $resource('/some/:url/', ..., ..., {
stripTrailingSlashes: false
}); Any feedback, anyone? |
This is the stupidest bug ever, angular has no business editing urls that have been explicitly defined by the developer. And why was this ever necessary in the first place? And 2 years to fix this? |
Thanks for being super constructive @j0hnsmith :) This has been triaged for 1.2.x, and it is potentially a breaking change for people who are depending on this functionality unwittingly! If you can put together a PR to make this work for you, you could let people dog-food it so that we can get a bit more certainty of it, and that would be awesome! We can try to look at it for 1.2.10, if not 1.3 (Oh, and just to correct you, this isn't really "angularjs" core, this is ngResource, which you are not at all forced to use with Angular) |
Until @nvie 's patch is in, the following will do for a workaround, even in firefox.
angular.module('ngResource').config([
'$provide', '$httpProvider',
function($provide, $httpProvider) {
$provide.decorator('$resource', function($delegate) {
return function() {
if (arguments.length > 0) { // URL
arguments[0] = arguments[0].replace(/\/$/, '\\/');
}
if (arguments.length > 2) { // Actions
angular.forEach(arguments[2], function(action) {
if (action && action.url) {
action.url = action.url.replace(/\/$/, '\\/');
}
});
}
return $delegate.apply($delegate, arguments);
};
});
$provide.factory('resourceEnforceSlashInterceptor', function() {
return {
request: function(config) {
config.url = config.url.replace(/[\/\\]+$/, '/');
return config;
}
};
});
$httpProvider.interceptors.push('resourceEnforceSlashInterceptor');
}
]); |
I've been dealing with this issue while developing server-side support for $resource in Django. (crud view in django-angular) The simplest workaround for Django is to not use trailing slashes in views used with $resource. E.g.
I'm in favour of that rather than monkey-patching $resource js. Anyway I hope this will be fixed soon. |
is this still open?! |
Fixed via #5560. |
🎊 |
Unreal. Spent I don't want to admit how long wasting my time trying to figure out what I was doing wrong only to find this. Why on earth was an explicitly set string being messed with in the first place? |
I have a module where I define a service like this:
.factory("Charts", function ($resource) {
return $resource("/api/charts/:chartId", {
}, {});
})
Then, on the controller I do:
var chart = new Charts({
name:$scope.name,
query:$scope.query,
since:$scope.since,
since_unit:$scope.since_unit,
interval:$scope.interval
}
);
chart.$save();
And on the server I'm receiving the POST to /api/charts instead of /api/charts/ that is what (I think) it should be.
There is a discussion in the list:
https://groups.google.com/forum/?fromgroups#!topic/angular/taypgj_D3YQ
The text was updated successfully, but these errors were encountered: