AJAX call to asp from bookmarklet - asp.net

I'm trying to create a bookmarklet that will start off an AJAX call to an aspx page I've written.
The code tests out perfectly when I place the javascript in a static html page, but when I try and call it off from a bookmarklet, the code will just hang at the xmlHttp.open("GET", url, true) part.
The code of the bookmarklet is basically this (found on several examples on the web):
javascript:(function(){
var s,
d=document,
a=function(o){ d.body.appendChild(o) };
s=d.createElement('script');
s.type='text/javascript';
s.src='http://localhost/squirt/sq.js';
a(s)
})();
This adds the contents of sq.js (the ajax call + some other processing) to whatever page the browser is currently at, and then calls off the ajax to my aspx page.
I'm using ASP 2.0 (with VS2008) and IIS 7. So far I've just been testing it on my home network.
I assume there must be some sort of permissions issue with the ajax call from an outside page, since, like I said, everything works fine from a static page. Is this an IIS setting I need to change to allow the call, or am I doing something completely wrong?

The XMLHttpRequest object is subject to a Same Origin Policy.
This is why the script your bookmarklet is loading can't use an XHR to get data from your server unless it's embedded in a page from your server.
Script added by dynamically adding a script tag will work though, as you can tell - your bookmarklet can load script from a different origin.
So there's your answer. Don't use an XMLHttpRequest object: dynamically load your script in the same way the bookmarklet does.
This is how JSONP works (actually there's a bit more to JSONP but that's how it gets around the SOP)
Actually, why not just use JSONP

Injecting JavaScript code on the page still has the same permission issues as code that is there normally. You can not make an Ajax call to a different domain. So if you are calling localhost from example.com, it is not going to work.
You might want to look at returning JSON from your service and make JSON calls with a script tag.
Eric

The code you're using there is rather ugly, I would suggest using something like this that I built: http://sktrdie.org/getScript.js
It works like this:
getScript("http://anotherdomain.com/something", function(data) {
alert(data); // the request is complete
});
On the http://anotherdomain.com/something it would have to return something like this, given you're using PHP:
echo $_GET["jsonp"]."('Testing data, you can put anything in here');";
Be sure to read about JSONP.

Related

ASP.NET log requests to Amazon S3 objects

I've put some objects in an S3 bucket and I want to log everytime a client makes a request to one of those objects.
I'm using Umbraco 4.8 as my back-end with some custom code running.
The solutions I've come up with:
Set the link to an ASP page that pulls the object from S3 and sends it back as the response. The problem I see there is then the client has to wait for ASP to load the file before it can begin downloading the file.
Set the link to an ASP page that logs the request and returns a Response.Redirect to the S3 object. To me this seems like an unnecessary redirect and the client might cache that redirect and not hit my server the next time they access that object.
Does anyone have any other solutions or thoughts on how to achieve this? Any help would be appreciated.
I would use jquery and google analytics. Add a class to each link that you want to track and then use jquery to manipulate the onclick event to something like:
link text
Replacing the three variables appropriately ('s3-Bucket-Request', 's3-actual-bucket-name', 'current-page'). If you then put the jquery at the head of each page you have a reusable function.
start:
link text
jquery:
$('.ga').attr("onclick", "__gaq.push(['_trackEvent', 's3-Bucket-Request', 's3-actual-bucket-name', 'current-page']);");
end:
link text
Depending on how accurate you need this to be, you could also do it client side. Using jQuery, etc, add a click handler to a href tags that makes an ajax request to a controller, logging the activity.

Easiest way to simply display confirmation that a webservice worked?

I'm calling an asp.net webservice from an ASP clasic page basically just with:
<a href='http://domain/webservice.asmx/command'>Command</a>
and when users hit that button it works but they're just shown an xml page. The function will either work or not so I was wondering if it'd be possible to just have a pop up box appear to tell them if it worked or not after they clicked it rather than redirecting them to an xml page.
I'd prefer to not have to use jQuery or another javascript library.
If that's not possible, is there any way to dress up the XML page? Currently it says 'This XML file does not appear to have any style information associated with it. The document tree is shown below.' at the top.
Also, the domain that the webservice is on is different to the domain that the website that's call the webservice is on. Not sure if that matters.
Thanks
Check out this MSDN Link on Calling A WebService From Javascript Using AJAX. No JQuery is required and it boils down to having to use the ScriptService attribute on your WebService method and adding a ServiceReference in a ScriptManager control. You can then easily call your WebService from Javascript and it will call another Javascript function when it finishes. It is in that response function where you can add your confirmation display.
be aware that this is a bad idea to let the user handle directly - web services are almost always called by your code rather than a client browser session. One reason is that raw error information would be hown to the client if there were a problem.
If you really want to do this, you can either:
Use AJAX (No framework required - just JS) or
You can make the webservice non-standard so it returns user-friendly content - perhaps by wrapping it in a website which calls the API behind the scenes and formats the response in a meaningful fashion.

Load ASP.Net User Controls via jQuery AJAX

I have mini modules(think iGoogle) that are currently loaded via the page calling LoadUserControl method and loading that control into PlaceHolders. I need to switch that implementation to loading the controls through a jQuery AJAX request. The problem currently lies in the fact that when I perform an AJAX Get, I can load the modules by appending them to the content but none of the functionality that would otherwise be working on a normal loaded control is there. For example, when I select a different option on the a DDL the page refreshes and nothing changes. I suspect because it is because the methods aren't being tied in when I perform a load through AJAX. Additionally when I use this method my flash content is not being loaded.
Am I doing something wrong here, or is there a better solution ?
$.ajax({
url: '/modules/UserModules.aspx?CID=12345',
type: "GET",
dataType: "html",
success: function(data) {
$('#column1').append($(data).find('div#lm li'));
$('#column2').append($(data).find('div#cm li'));
$('#column3').append($(data).find('div#rm li'));
alert('Load was performed.');
}
});
When you post back to the server, the server doesn't know about your user control because it was added to the page dynamically. Actually, you render the UC HTML, then add part of the rendered HTML to your page.
I would recommend steering clear of posting back to the server and using jQuery to retrieve any data using a Page Method or web method when you make a selection using your DDL.
I'm not sure I see the utility in using a UC for this. There are a number of ways to do this sort of thing. Like Jamie said, you can have a plain .aspx page that uses web methods. An asmx page. You can also not use web methods and just do as you would with php or classic ASP by writing your string results directly and processing them (shouldn't be your first choice though!).
But the most important thing you can take from this is debugging. Put a break point in your UC code to track server side. Use Firebug: open it, choose console and watch to see if your GET requests are actually doing what they need to. These days, you rarely need an alert to debug.

Accessing a control in asp.net content page through Javascript

I have a form in my content page for which I am doing some client side validations via Javascript. The Javascript behaves as expected if I place the JS code directly in the content page. But if I place the JS code in it's own file and try accessing that from the content/master page (through the script tag's src attribute), I get a run time error when the validation function in JS being called.
To be specific, I get the below error.
Microsoft JScript runtime error: Objected expected/required at this line - document.getElementById('<%=txtemailId.ClientID %>').value
txtemailId is in the content page.
Javascript code is placed in validation.js and accessed via master page.
The reason I guess is that when .net is parsing the files, it is unable to substitute txtemailId.ClientID with the client side value that would be generated later on. So, how should one go about it? Thanks!
The answer to this is quite simple.
Within your content page declare an in-line JScript variable, make sure this is above your tag.
<script>
var emailClientId = <%=txtemailId.ClientID%>;
</script>
Within your include.js file make use of the globally scoped emailClientId variable.
Obviously this is a bit clumsy because not all of the JScript code is contained within the include.js file, which makes it difficult to debug / diagnose as it is not clear specifically where the value is coming from. You should clearly comment / document this within your code to make maintenance of he codebase easier in the future.
You're right, the code <%=txtemailId.ClientID %> will only get replaced with the real client ID by ASP.Net if this code is in an ASP.Net file. So if you put this javascript in a separate .js file, ASP.Net will know nothing about it, and the code will not be parsed.
The easiest way to achieve this is to make the control IDs parameters of your functions. This way you can have the calling javascript code in your .aspx (or .ascx) file, along with the <%=txtemailId.ClientID %> code.
Standalone .js files are not run through the ASPX parser, so your expression is not being evaluated.
To solve the problem, you could set global variables (or function parameters, or something else) in the ASPX files with the IDs of the controls, then use them in the standalone .js file.
Alternatively, you could uses class names (which don't get mangled) instead of IDs. (This is very simple using jQuery)
An approach like this is best suited for something you want to achieve:
validation.js
var Validation = {
EmailId: null,
Validate: function() {
var email = document.getElementById(EmailId).value;
}
}
page.aspx
Validation.EmailId = '<%=txtemailId.ClientID %>'; //initialize
Validation.Validate(); //whenever you want to validate

removing duplicate script from page

I am trying to make use of the yahoo exceptional performance rule : avoiding duplicate script
To do so i would like to be able to know whether or not a script was already added to the page before injecting it in the page. It looks like i can't figure what has been added in asp.net code behind unless i have a scriptmanager added to the page. but i would like to avoid using asp.net AJAX. From the description of the rule, it looks like it is something possible in php though.
Assuming that i can't do the check in my code behind, i was considering using jQuery $.getString function but it doesn't check before fetching the script. If i was to choose the javascript file, would i have to parse the whole http response in order to figure out which script was loaded on the page?
If the page is registering the scripts with the ASP.NET Page.ClientScript Register APIs then you can use Page.ClientScript.IsClientScriptIncludeRegistered. On the other hand, if you are using those APIs you don't really need to call it, since it already ensures only one of each is registered.
http://msdn.microsoft.com/en/us/library/system.web.ui.clientscriptmanager.isclientscriptincluderegistered.aspx
If the page just has regular ole script elements statically in the markup, and you need to detect if a script is loaded on the client side, you will have to get all the script elements on the page and look at their .src values. The thing with that is that some browsers automatically resolve that url to a full path, not just the one you declared. So, you can account for that in various ways -- you can just search for the end of the string being the script you want, or you can cause the url you want to compare with to also be resolved by setting it onto a dynamically created script element (which you never add to the DOM but is still resolved for you).
This is just off the top of my head, sorry if I get something wrong:
var s = document.createElement("script");
s.src = "foo.js";
var loaded, scripts = document.getElementsByTagName("script");
for (var i = 0; i < scripts.length; i++) {
if (scripts[i].src === s.src) {
loaded = true;
break;
}
}
if (loaded) {
// this script is already loaded
// assuming you dont have multiple copies in different locations
}
You don't need to use any client-side scripting to do this... you can do this in your code behind using the ClientScriptManager without needing to make use of ASP.NET AJAX (I think you're confusing ClientScriptManager with ScriptManager*) in your control/page just use:
ClientScript.RegisterClientScriptInclude("some-script", "myScript.js");
or from your user controls:
Page.ClientScript.RegisterClientScriptInclude("some-script", "myScript.js");
This will use the key "some-script" & only register one copy of the script on the page.
*To be clear I think the confusion is arrising from the difference between these:
ClientScriptManager if a server-side helper class which is used to manage client side scripts (in other words its whole purpose is to do exactly what you are trying to do). It is accessed via the Page's ClientScript property.
ScriptManager is a Control used to aid client side Ajax scripting in ASP.NET AJAX
(hell I even confused myself & gave the wrong example code initially)
well that wouldn't actually work in a master detail scenario with multiple web user controls.
Then you wouldn't have control over who has to do the script initialization if the web user control is dynamic.
It's easier to link once, but a developer would have to weigh his options between ClientManager and using a script load.
yeah you have to parse the whole response...
why don't you create a javascript file and put all of your javascript there and then import that javascript file in your code??? in this way you can get rid of duplicate script insertion.

Resources