Complex $resource url template - javascript

So I want to call REST service with the following URL patterns:
1.domain.com/service.svc/action1/sessionid/objectid
2.domain.com/service.svc/action2/sessionid/objectid/objectid2
3.domain.com/service.svc/action3/sessionid/objectid
4.domain.com/service.svc/action4/sessionid/objectid/objectid3/objectid4
5.domain.com/service.svc/action5/sessionid/objectid4/objectid5/objectid6/objectid2
and I ended up with this resource object:
var object = $resource('domain.com/service.svc/:actionName/:sessionId/:objectid:objectid4/
:objectid2:objectid3:objectid5/:objectid4:objectid6/:objectid2:', {}, {});
And I can call:
object.get({
'action1': action1,
'sessionid': sessinId,
'objectid': objectid
})
I see the problem here with the URL template, it looks cumbersome to read.The second problem is that URL number 2 expects objectid2 in one location in URL, and then URL number 5 expects the same parameter at the end of url.This breaks URL template, so I had to rename one of the them.Is there a better solution for this particular problem, and what are the best practices regarding REST services with these complex URI's ?

Related

AngularJs How to sanitize URL in the controller?

I was wondering if there is a programmatic way of sanitizing (user provided) URLs in AngularJs 1.5. I know there is $sanitize service, which is for sanitizing HTML but I can't find something that would work for URL.
Sample Good URL:
http://www.somedomain.com
Sample Dangerous URL:
javascript:document.write('Time for some fun');
There is undocumented $$sanitizeUri service that does this. It's basically a function that adds unsafe prefix to supplied URL. There's no need to use it for URLs are bound to href like
<a href="{{url}}">
because this is already done by compiler ($$sanitizeUri is used there).
For malformed URLs in general it may be better to process them by hand and possibly add http:// if it doesn't contain acceptable (http/https) protocol.
I ended up performing the following regex test (inspired from $$sanitizeUri service) on the URLs and then performing a special operation whenever the check failed.
function navigateToUrl(url) {
var safeWhiteListRegex = \^(https?|ftps?|file?):\/\/\gi;
if (!safeWhiteListRegex.test(url)) {
// url = ...;
} else {
$window.open(url, "_blank");
}
}
Along the way, one of my friends also discovered the #braintree/sanitize-url Node Module, which I also think is something people can use for situations like this.

Passing a query string to a request as an actual string using Node and Express

So, basically what I am doing is scraping a webpage, getting all of the data I want and displaying it on a webpage on my site. When scraping this specific page i need the link within the 'href' tag. However, this particular site doesn't use regular links. Inside the 'href' tag is a query string. My plan was to take what was inside the 'href' and create a url to make my next request, but now when I try to pass the query string into the url, I can not access it in Node via req.params
I want to know if there is a way to maybe pass a query string without the server thinking it is a query string, or will I have to use req.query to take all the params and build the URL again from scratch?
Here are some examples of what I am talking about:
page1.ejs:
some.href = "?variable=bleh"
Server-side handling:
app.get('/display/:string', function(req, res) {
var url = "http://theurlineed.com/" + req.params.string;
});
This code does not work. When i click on the link it tells me it couldn't get /display/?variable=bleh
You need to encode the query string so that it is not treated like a query string in the URL:
some.href = encodeURIComponent("?variable=bleh");
So then your URL will be: /display/%3Fvariable%3Dbleh. As mentioned in the comments, Express will automatically decode the value in req.params.string so it will be the right value.

Ext Js proxy pass parameter

I want to pass a parameter to my Store proxy to retrieve the right data from the server. I need to pass the parameter without the name prefix and just the value.
Instead of this kind of url :
myAppUrl/collections/units?collectionId=54
which can be done like this:
myStore.getProxy().extraParams.collectionId = 54;
I want to have a call like this:
myAppUrl/collections/54/units
My web service is adapted for both calls I just need the correct client code to pass the parameter.
Please help and advise.
An old question, but I write for anyone with this problem. I implemented the idea of #Saki in this package (for ExtJS 6) because of my own needs:
https://bitbucket.org/alfonsonishikawa/extjspackages/wiki/Server%20URL%20Placeholders
The idea is being able to use an URL like:
proxy: {
type: 'rest',
url: 'myAppUrl/collections/${collectionId}/units',
appendId: false
}
With that package, you just have to configure your proxy like above and call #load() with params:
store.load({
params: {
collectionId: 54
}
});
(getProxy().extraParams can be used as default value)
This is the source code as example that you asked #Saki about.
It looks almost like REST request but not exactly as REST places indexes at the end of url. You could solve it by implementing a custom buildUrl of Ajax or Rest proxy. In any case, see how is this method implemented in Rest proxy.
you can set your url dynamically and then call load method of store using below code.
store.getProxy().setUrl('your new url');
store.load();
but if you gonna use this method then you have to set correct url every time other-vice may be you will get wrong data.

Django: reverse parametrized url in JavaScript

let's say one of my urlpatterns looks like this.
url('^objects/update/(?P<pk>\d+)$', views.UpdateView.as_view(), name = 'update-object'),
I need to redirect user to the update page depending on the selected object (the list of objects is populated using Ajax). So I'd like to pass that named url pattern to the JavaScript, in order to build the actual url on the client side.
Example of what I want to achieve:
pass the name 'update-objects' to the function
get the actual url pattern, replace (?P<pk>..) with {pk}
pass the result to the javascript, resulting in : objects/update/{pk}
any tips?
thanks
to make it more clear: at the moment of rendering, I can't do url reverse because the PK is not known yet. I need to make kind of javascript-urlpattern which will later be converted to the real url (i.e. my JS code will replace {pk} part with the actual pk value)
The actual URL reversing must happen on the server side. There are several ways to do this, and the most elegant of these probably depends on how exactly your script and markup are set up for this. One thing I've done recently is to attach the URL to a logical element using HTML5 data attributes, which are easy to retrieve using jQuery. If you're not using jQuery, I'll leave it up to you to translate to pure JS. You haven't provided any code or specifics for your client-side, so I'm kind of shooting in the dark here, but maybe this will give you the idea:
Django HTML template:
<ul class="object-list">
{% for object in objectList %}
<li data-update-url="{% url update-objects object.pk %}">object.name</li>
{% endfor %}
</ul>
JS:
$('.object-list').on('click', 'li' function () {
var updateUrl = $(this).data('update-url')
...
});
It sounds like you need to make an additional ajax call once the object has actually been selected. Don't try and second guess your url.conf by trying to work out the url on the client side - you'd just be making trouble for yourself later. Wait till you can get a pk, then use django's reverse function to give you your url (doing anything else violates DRY).
How about creating a simple view that returns the url -
from django.core.urlresolvers import reverse
from django.http import HttpResponse, HttpResponseBadRequest
def get_url(request):
if request.is_ajax() and request.method == 'POST':
obj_id = request.POST['obj_id']
url = reverse('object-update', kwargs{'pk': obj_id})
return HttpResponse(obj_id)
return HttpResponseBadRequest()
Then write a javascript function that gets the url using an ajax call to your new view and then redirects. You'd call this function as soon as the object's been selected. I would suggest using JQuery to do this, pure javascript will require you to write more code, and probably write browser specific code (depending on your target). Also it supports dealing with django's csrf protection (you'll need to implement this for ajax calls if you haven't already).
var redirect = function(obj) {
$.ajax({
url: '/your-get-url-view/',
method: 'post',
data: {'obj_id': obj},
success: function(url){
window.location = url;
}
});
}
I'm afraid I don't know how you're getting from the selected object to the pk (For simplicity I've assumed it's available to the redirect function) - you may have to do some processing in the view to get there.
I haven't tested the above code, but it should give you an idea of what I'm suggesting.
Try this one:
Reverse method for generating Django urls
https://github.com/mlouro/django-js-utils
One more
https://github.com/Dimitri-Gnidash/django-js-utils
If you have a URL that only has one PK field in it, you could resolve it with any number (e.g. 0), then substitute the number as required.
In my scenario my URL had a pk then an upload_id, so I had to replace on the right most instance of a 0, with <upload_id>, which the JS would replace this string occurance as required:
detele_url_upload_id_0 = reverse(f'{APP_NAME}:api_upload_delete', args=[pk, 0])
prefix, suffix = detele_url_upload_id_0.rsplit('0', 1)
context['generic_delete_url'] = prefix + '<upload_id>' + suffix
Then in the JS:
const deleteUrl = genericDeleteUrl.replace('<upload_id>', uploadId)

Should Backbone.js grab GET parameters from URL?

I am trying to implement a search function for my website. When the user types a search term foobar into a input box and submits it, he is redirected to http://mydomain.com/search?query=foobar.
Problem:: How should I grab the GET parameters query from the URL, and send it to the backend and get a array of results back as a JSON response? Should I even do it this way?
My current attempt below does not even cause the search function to be triggered.
Router
var AppRouter = Backbone.Router.extend({
routes: {
'search?query=:query': 'search'
// ... and some other routes
},
search: function(query) {
this.photoList = new SearchCollection();
var self = this;
this.photoList.fetch({
data: {query: query},
success: function() {
self.photoListView = new PhotoListView({ collection: self.photoList });
self.photoListView.render();
}
});
}
});
var app = new AppRouter();
Backbone.history.start({
pushState: true,
root: '/'
});
There have been several issues filed against Backbone for this very issue. There is an existing plugin that works well for this:
https://github.com/jhudson8/backbone-query-parameters
Alternatively, I'm currently using query string parameters in a mock API that matches Backbone's route matching. Looks something like this
Route
"/api/v2/application/:query"
Query
application: function(query) {
var params = $.deparam(query.slice(1));
// params.something...
}
As to your actual issue at hand how are you redirecting to index.html to support pushState?
I hit this same issue and contemplated using backbone-query-parameters, but that should be considered generally an incorrect approach.
The url query string is not meant for the front end. They get sent to the server and force a refresh when navigating from page.html to page.html?something=something.
You should be using hash fragments instead. i.e. http://www.example.com/ajax.html#key1=value1&key2=value2 then just get those values the normal backbone way and build your request params from that.
See https://github.com/jashkenas/backbone/issues/891, https://developers.google.com/webmasters/ajax-crawling/docs/specification, https://www.rfc-editor.org/rfc/rfc3986#section-3.5
You can always read the URL via jQuery URL plugin. It works well.
https://github.com/allmarkedup/jQuery-URL-Parser
There are very few cases when you need to read the URL and extract the GET params. I think that you are doing things wrong and here are my options:
1) if you are having just one page in your app (single app page) you can display results as they type in your input field or after they hit submit
2) if you are redirecting the user to a different page that means you can bootstrap data so that after the page is loaded backbone will just have to render your results and only make other requests if you change your search word
3) you can have a javascript variable which is initialized on page load directly from the server where working with GET params is probably easier

Categories