jquery ajax calls in an mvc site not sharing logged in session - asp.net-mvc

as in the title
we're firing
$('#id').load('someUrl', function(){/*some stuff*/});
But it seems to be being passed to the login form because it's not logged in?!
The user is logged in. Is this normal?

This happened to me too, but the cause was not that ajax is going crazy - which it may look like - but that the URL was not correct.
The website was initially hosted on localhost, without any alias, so I had a working URL like localhost/controller/action.
Then I moved the website under an alias - so the website's URL was localhost/alias. At this point, two strange things happaned to SOME ajax requests:
- the requests were prompted for authentication (the website was using windows authentication)
- the requests' session was different than the one of the page which launched the request
The problem was that some URLs were hardcoded in the js code. So we had code like "url: '/controller/action'" in the ajax calls code, and this URL didn't take into consideration the alias under which the website was hosted in IIS.
The solution was to declare a js variable in the page and assign it the URL built the right way, with Url.Action, and then use the variable in the ajax call:
Page:
<script type="text/javascript">
var ajaxUrl = '#Url.Action("actionname", "controllername")';
</script>
Js file:
$.ajax({
type: 'POST',
url: ajaxUrl,
...

Related

JQuery Mobile Linked Listview not working properly?

So, I'm making an mobile e-commerce app using JQuery Mobile and I'm having the following issue.
After logging in, the app takes the user to the store area which consists on a linked listview populated with JSON data. Now when the store page first initialises, the links don't work, but when I refresh the page they work just fine. Does anyone know why I'm getting this behaviour?.
Note: I'm using a multipage template, to navigate from #store page to #product page.
Here the javascript I'm using for this:
$(document).on("pagebeforecreate","#store", function() {
getProducts('',
function(data){
let products = data.products;
storeProducts(products);
$(".product-list").html('');
$.each(products, function(i, item){
$(".product-list").append(`
<li>
<a href="#product" data-index="${item.prod_id}">
<img src="${item.picture}" alt="">
<h2>${item.prod_name}</h2>
<p>${item.prod_desc}</p>
<small>Price: <strong>€${item.unit_price}</strong></small>
</a>
</li>
`).listview("refresh");
});
},
function(e){
console.log(e);
},
function(data){
console.log('always');
});
});
function getProducts(param, success, error, always){
$.ajax({
type:'GET',
url:`./ajax/products-ajax.php?${param}`,
dataType: 'json',
async:true
}).done(function(data){
success(data);
}).fail(function(e){
error(e);
}).always(function(data){
always('always');
});
}
Thanks in advance.
UPDATE:
Hi deblocker,
Thanks again for your answer. There's no errors showing up in the console log. I tried turning off the cache in my browser and still have the same issue. Let me see if I can explain better what I am trying to do.
I am trying to make this app using JQuery Mobile for the frontend and PHP for the backend. I've got an index.php with links to get you either to login or register. Let's say that you select the login option, that's going to take you to login.php where there is a form which when you submit it makes an ajax request to the server to do authentication. Supposing the response is successful, that'll redirect you to store.php which is where the listview lives. As I say before, when you land in store.php after logging in the links in the listview don't work, however if you refresh the page the work as they are supposed to.
Here is what was causing the problem:
When redirecting the user to store.php after authentication, JQuery Mobile's Ajax navigation was grabbing the first page I had in there (store.php is multipage, containing #store and #product) and injecting it on top of what already was in the DOM. Of course when I clicked on my links these didn't work since there was no page containers with id = "product" in the DOM. When I refreshed the page JQuery mobile made a http request to the server, this time getting the full store.php with both pages #store and #product, hence the links would work as they were supposed to.
My solution: have both #store and #product as external pages. By separating them and calling them as external pages I avoid this issue with the Ajax navigation.

using angular router in custom pages

I have a rails app with dashboard page. So the page will be http://mywebsite.com/dashboard. It has few links available which will load pages via ajax and show it in a div section inside the dashboard page. Its all working fine. So lets assume I want to use angular here and I specify code like below.
var myapp = angular.module('myapp', ["ui.router"])
myapp.config(function($stateProvider, $urlRouterProvider){
$stateProvider
.state('route1', {
url: "/route1",
templateUrl: "route1.html"
})
})
My doubt is that:
So in here if dashboard is the root url then the url generated is http://mywebsite.com/#route1
What if my dashboard page is defined like this
http://mywebsite.com/dashboard and I want to define route like http://mywebsite.com/dashboard/#route1
Note: Its not a single page application. But I want the dashboard page
to be like a single page one..
This will work fine and the route will be relative to your URL
http://mywebsite.com/dashboard.
If you were using HTML5 mode with Angular UI router if you try and interoperate the full URL. But because you are not using HTML5 mode, Angular UI router routes using #.

In an iframe, build url from parent page hostname and new params

I have two sites which communicate with each other. I'll call them mainsite.com and backend.com for this example.
mainsite.com is the site that people go to, and this loads an iframe which loads in backend.com, which is a Rails site that handles all of the login & signup stuff. At the end of the login process, backend.com generates a url which has an encrypted set of params which are used to log the user into mainsite.com.
The way that this is currently working is that backend.com controller generates a url like this "http://mainsite.com?auth=2347qweiuyqi" and saves it in a variable called #redirect_url, then (in the iframe) renders out some html which contains some javascript to redirect the parent page:
<script type="text/javascript">
$(function(){
window.top.location.href = "<%= #redirect_url %>";
});
</script>
This is working fine. However, we have a new situation where people can now access mainsite.com via a load of different urls (all subdomains on other sites, like mainsite.foo.com and mainsite.bar.com)
Now, when i redirect them to the auth url on mainsite, i want them to stay on whichever domain they're on. So, if they're on mainsite.foo.com, and loading backend.com in the iframe, then at the end of the login process i want to redirect the parent window to mainsite.foo.com?auth=2347qweiuyqi. Similarly, if they're on mainsite.bar.com they should be redirected to mainsite.bar.com?auth=2347qweiuyqi
My initial attempt at this was to change the javascript to get the domain name from the parent window, and build the redirect url by adding the params onto the end, then redirecting to this url. However, the iframe can't access the parent domain name because of cross-domain protection (ie the domains, "mainsite.foo.com", and "backend.com", don't match.
My next attempt was to have a javascript function on mainsite.com which takes the auth param and redirects to a url consisting of the current domain with that param added onto the end. But, i can't call a parent window function because of the same cross-domain restrictions.
How can I get past this? I have complete control over the content of both sites.
One solution which i know would work, but is a bit of hassle to set up, is to pass through the mainsite domain name through as a parameter in the src attribute of the iframe to backend.com, and then make sure that backend.com hangs on to that through the whole login/signup process, so that at the end of the process it can use it to build the whole url to redirect to. But, it feels like there should be a simpler way.
thanks, Max
EDIT - i've solved this by, when the first request comes through from mainsite.com to backend.com, saving the hostname of request.referer into the session, and then, later on when i come to do the redirect, looking it up from the session and adding the auth params on. This works but it feels a bit unsatisfactory so i'm interested in nicer solutions.

Can I capture a param but avoid showing it in the url?

I would like to capture the id of an element that is clicked on and then pass that id to the controller, all without showing the id in either the link or the url param, and without having to write custom ajax loading. Anything like that available in rails out of the box?
What are you trying to achieve (what's the end goal)? It sounds like you want to communicate between the client and server without using ajax or encoding params in the user's url.
The usual ways of doing that, with those constraints, would be:
1) Wrap the click target in a form, and set the id to a hidden value. On click, just post the form. This will require a page refresh, but since it's a POST, won't muck up the url.
2) Set the id in a cookie, force a page refresh, read the id on the server and unset it. This will obviously also require a page refresh, but won't encode anything in the url.
3) Use an invisible iFrame to load a url with the param of interest. This won't require a refresh and the url can be anything, since the user will never see it.
If a page refresh/change is fine, the form route is probably best. If you don't want the page to refresh though, an xhr request is clearly the best solution. It's really simple to do, but an iFrame solution would be a hack that probably meets your needs too.
I am assuming you don't want to show the ID to the user but you need the element ID to hit the server.
You could use a custom request header, but that would require an AJAX approach. Here's a sketch with JQuery
$("a.sends_element_id").click(function(e){
e.preventDefault();
$.ajax({
url: $(e.target).attr("href"),
type: "GET",
beforeSend: function(xhr){xhr.setRequestHeader('X-Element-ID', $(e.target).attr("id");},
success: function(result) {
// Do something here to display the page
// Eg. http://stackoverflow.com/questions/824349/modify-the-url-without-reloading-the-page
}
});

MVC Ajax action relative to current controller

I'm trying to get an Ajax call from a link in a master page.
So I want to specify only the action relative to the current page/controller.
i.e.
$.ajax({
url: '/Save',
type: "GET",
// .. etc
});
I want to call the "Save" action of whatever controller served the page. I thought this would work straight off, but it doesn't appear to. Is there an elegant solution?
If you got this straight into your view, you could do
$.ajax({
url: '#Url.Action("Save")',
type: "GET",
// .. etc
});
If not, and javascript is in external file, you could attach url generated with Url.Action to element as data-? html5 attribute. And then dynamically read that attribute value before doing ajax call.
<input type="text" data-save-action-url="#Url.Action("Save")" />
You should never hardcode url's in asp.net mvc. Always use Url.Action. It inspects your routing configuration when generating urls, and will always return correct value according to it. If you hardcode urls, your application may become unusable when you change routing configuration. And you will have to change every single url in you application manually.

Resources