js "scripts" folder name prepended to XMLHttpRequest calls - javascript

I have a javascript file named myscripts.js in the "scripts" folder of my webserver. It could be accessed with this:
http://www.example.com/scripts/myscripts.js
Within myscripts.js is a javascript function which makes a XMLHttpRequest call to somemethod.html of my website. Here is the calling code:
xmlhttp.open("GET","somemethod.html",false);
99% of the time everything works fine. But I am finding some browsers are prepending "scripts/" to the call. So the result is a call like this:
http://www.example.com/scripts/somemethod.html
when it should be this:
http://www.example.com/somemethod.html
This is a custom built webserver (i.e. I basically handle ALL requests).
Should my webserver be able to handle this? Or is this just some fluky browser that I should not worry about?
Should I not be using "relative" paths in the javascript? And instead use absolute calls in the java script? e.g.: instead of "somemethod.html" it should be coded like this:
xmlhttp.open("GET","http://www.example.com/somemethod.html",false);

It's absolutely fine (and overwhelmingly the standard of practice) to use relative paths in the JavaScript, just be aware of what they're relative to: The document in which you've included the JavaScript (not the JavaScript file.) You seem clear on this, but just emphasizing.
I've never seen a browser get this wrong. It's possible the requests you're seeing are from a poorly-written web crawler looking at the source of the JavaScript rather than doing something intelligent like figuring out where/how it's run.
Just for clarity, though, about the relative thing (more for lurkers than for you):
Given this structure:
foo.html
index.html
js/
script.js
In that structure, if you include script.js in index.html:
<script src="js/script.js"></script>
...then use code in that script file to do an XHR call, the call will be relative to index.html, not script.js, on a correctly-functioning browser.

I never use relative requests, I built my own url handing js code to build up and pass urls around with a 'toString' method to give me exactly the url I need.
Also as an aside, try not to use synchronous XHR calls anymore, ideally you should use async and call backs, it's a pain, but it's for the best.
client . open(method, url [, async = true [, username = null [, password = null]]])
Sets the request method, request URL, and synchronous flag.
Throws a "SyntaxError" exception if either method is not a valid HTTP method or url cannot be parsed.
Throws a "SecurityError" exception if method is a case-insensitive match for `CONNECT`, `TRACE` or `TRACK`.
Throws an "InvalidAccessError" exception if async is false, the JavaScript global environment is a document environment, and either the timeout attribute is not zero, the withCredentials attribute is true, or the responseType attribute is not the empty string.
source: http://xhr.spec.whatwg.org/#the-open%28%29-method

Related

JQuery AJAX URL Local or Absolute

I have a portion of my web application that uses AJAX. I am using the JQuery AJAX call to add and remove items from the users shopping cart, and it works fine. The URL that I pass as a parameter in the AJAX call is the url-mapping defined in the web.xml file, minus the leading forward slash.
I tried to replicate this with another place in the application where I would like to use AJAX, but this time, the Servlet GET is not even being called at all. I have alerts in the javascript function, so I know the function is being called. Is there a way that I can see (within the ajax function call) what the fully qualified URL is that the GET request is being made to? Also, what is the 'rule' with respect to the AJAX URL? Is there a way that I can get to the context root? My Servlet is mapped to www.mydomain.com/contextRoot/un
I would rather not have to hardcode the context root into the function call, that way if it ever changes, I don't have to update all my javascript functions.
The "rule"
Ajax requests (or any http request from the page) that does not start with a / (or the full domain path) is relative to the current HTML file path.
How to view GET requests
Use the debugging tools in Chrome/Firefox or something like Fiddler2
How to get server root
If it is a simple www.host.com:
var root = location.protocol + '//' + location.host;
(Not sure if this works for context based domains).
You do not mention what server technology you are using, but if you are using MVC/Razor you can inject the server root into a Javascript variable with something like this in your master page header:
<script type="text/javascript>
window.domainRoot = "#(Url.Content("~/"))";
<script>
this injects a javaScript line like:
window.domainRoot = "http://www.mydomain/mycontext/";
you can then reference window.domainRoot from any JavaScript code.
If you are using PHP there will be an equivalent way to inject the server root.
A simple browser debugger (F12) and you can read the network traffic send.
From here it is possible to see all the details (sent and/or received)
I think The url plus parameter is contextRoot/un?para=*.

Using a javasscript closure that exist in an external site

I want to use a javascript file that exist in another host.
the file contain a closure on it
//http://ExternalHost.com/somefile.js
(function(){
//...........
//...........
return { x:1, y:2 };
})();
and I want to use the returned object of the closure.
My question is
1) how can I get that file?
2) how can I use the return value of closure?
I know we can use the returned value if the file likes below
//http://ExternalHost.com/somefile.js
window.returnedObject = (function(){
//...........
//...........
return { x:1, y:2 };
})();
but the problem is: window.returnedObject is global!
Well, let's analyze it.
somefile.js resides in another domain. So, you should request it from yourdomain.tld and it's on externalhost.com. You have many options:
Request it via a simple HTTP Get method, which is issued by putting a <script /> tag anywhere on your DOM. This way, browser gets the file, executes it on its arrival, and you have to way to hook into this process, unless you and external host both agree on some similar protocol like JSONP, which is of course for data, not for libraries. So, this option is not useful.
You use XMLHttpRequest to load the file either synchronously or asynchronously. But XMLHttpRequest is by design under strict control of same-origin policy. So, external host should let you use it via some HTTP Headers, like Access-Control-Allow-Origin. This of course is applicable to normal request too. However, when you use XMLHttpRequest, you have the chance to hook into the load of the content, and do something on it. However, in this case, browser compiles JavaScript and runs it before giving it to XMLHttpRequest (your ajax call). So, again no use.
Understand the true meaning and philosophy of closure in JavaScript. It's like private access modifier in object-oriented programming. Technically it's there to NOT ALLOW you to access it :D. This options works. But it only increases your knowledge, to not expect to use that closure.
So, I think you can't AMAIK.

Why does this cross-domain request workaround work?

In this John Resig article, he's is dealing with a dictionary-sized list of words with javascript, and he's loading the content via ajax from a CDN.
The words are loaded in with newlines separating the words. Then he says cross domain fails:
There's a problem, though: We can't load our dictionary from a CDN!
Since the CDN is located on another server (or on another sub-domain,
as is the case here) we're at the mercy of the browser's cross-origin
policy prohibiting those types of requests. All is not lost though -
with a simple tweak to the dictionary file we can load it across
domains.
First, we replace all endlines in the dictionary file with a space.
Second, we wrap the entire line with a JSONP statement. Thus the final
result looks something like this:
dictLoaded('aah aahed aahing aahs aal... zyzzyvas zzz');
This allows us to do an Ajax request for the file and have it work as
would expected it to - while still benefiting from all the caching and
compression provided by the browser.
So, if I'm reading this correctly, simply adding his method dictLoaded('original content') around the original content alone causes the ajax request to not fail.
Is that (turning it into a function + param) really all it takes? and why does JSONP solve the problem of cross domain access restriction?
the <script> tags can load any JS file from anywhere (even cross domain). The nice thing that comes with it is that the code inside that script is also executed, therefore, a method of bypassing cross-domain restrictions.
The problem is, when the code gets executed, it's executed in the global scope. so having this code:
var test = 'foo'
will create a test variable in the global scope.
To mitigate this, you use enclose the reply in a function. This is the "P" in "JSONP" which means "padding". This encloses your reply in a function call.
So if your foreign script has:
myFunction({
test : 'foo'
});
It calls myFunction and passes an object with test key which has value foo. The receiving function would look like:
function myFunction(data){
//"data.test" is "foo"
}
Now we have successfully bypassed the cross-domain restriction. The essential parts needed are:
the receiving function (which can be dynamically created and discarded after use)
the "padded" JSON reply
Is that (turning it into a function + param) really all it takes?
Yes.
and why does that solve the problem of cross domain access restriction?
You should read about JSONP. The idea is that you can now include a <script> tag dynamically pointing to the resource instead of sending an AJAX request (which is prohibited). And since you have wrapped the contents with a function name, this function will be executed and passed as argument the JSON object. So all that's left for you is to define this function.
It is because of the JSONP statement that he added.
"JSON with padding" is a complement to the base JSON data format. It provides a method to request data from a server in a different domain, something prohibited by typical web browsers because of the Same origin policy.
This works via script element injection.
JSONP makes sense only when used with a script element. For each new JSONP request, the browser must add a new element, or reuse an existing one. The former option - adding a new script element - is done via dynamic DOM manipulation, and is known as script element injection. The element is injected into the HTML DOM, with the URL of the desired JSONP endpoint set as the "src" attribute. This dynamic script element injection is usually done by a javascript helper library. jQuery and other frameworks have jsonp helper functions; there are also standalone options.
Source: http://en.wikipedia.org/wiki/JSONP

How to get an included js file's contents without xhr?

is this possible?
<html>
<script src="local.js>
<script>
// get contents of local.js file here without doing an ajax call?
</script>
</html>
local.js resides on the same server, and I know that by doing an xhr call I can get its contents (if not on file://).
But, as it is already requested synchronously by the browser, its contents is known to the document so I hope there is a way to access it? The document.scripts collection was no help to me.
Somewhat like getting innerHTML (which works for scripts defined in-page)?
I'm not sure on how to get the included javascript code, nor why you would need this, but how about going the other direction?
Instead of having a script tag, make a XHR call to the file and eval its contents + keep its contents as a variable also.
**Disclaimer: I cannot see why you would need this, nor would I actually suggest you use this method, but it's a work-around.
Are you assuming XHR will not use the cached version? It will, there may be a request, but it should be fast (reuse the same HTTP connection) and return 304 (not modified). So the cached version will be used unless your JavaScript file's HTTP response headers prohibit or do not specify caching directives (but usually they should).
I suspect that while the contents of the script are known to the browser, they're not known to the document, and are therefore not accessible via the DOM API. So you will have to use the XHR approach. With a bit of luck, if you ensure the script is properly cached, the XHR request will pull the script contents from the local cache anyway.

Script puzzle <script src="ajaxpage.php?emp_id=23" />?

Very simple Ajax request taking employee id and returning the user info as HTML dumb.
Request ajax("employee/info?emp_id=3543")
Response id = 3543name = some name
This is just another simple JS trick to populate the UI. However i do not understand how something like below is equally able to execute correctly and dump the HTML code.
<script type="text/javascript" src="employee/info?emp_id=3543" />
When page encounters following code it executes like the ajax request is executed and dumps code into page. Only difference is its no more asynchronous as in case of Ajax.
Questions :
Is this correct approach ? its +ves and -ves.
Which are the correct scenarious to user it?
Is this also means that any HTML tag taking "src" tag can be used like this?
I have used this kind of javascript loading for cross domain scripting. Where it is very useful. Here is an example to show what I mean.
[Keep in mind, that JS does not allow cross domain calls from javascript; due to inbuilt security restrictions]
On domain www.xyz.com there lies a service that give me a list of users which can be accessed from http://xyz.com/users/list?age=20
It returns a json, with a wrapping method like following
JSON:
{username:"user1", age:21}
If I request this json wrapped in a method like as follows:
callMyMethod({username:"user1", age:21})
Then this is a wrapped json which if loads on my page; will try to invoke a method called callMyMethod. This would be allowed in a <script src="source"> kind of declaration but would not be allowed otherwise.
So what I can do is as follows
<script language="javascript" src="http://xyz.com/users/list?age=20"></script>
<script language="javascript">
function callMyMethod(data)
{
//so something with the passed json as data variable.
}
</script>
This would allow me to stuff with JSON coming from other domain, which I wouldn't have been able to do otherwise. So; you see how I could achieve a cross domain scripting which would have been a tough nut to crack otherwise.
This is just one of the uses.
Other reasons why someone would do that is:
To version their JS files with
releases.
To uncache the js files so that they are loaded on client as soon as some changes happen to js and params being passed to URL will try to fetch the latest JS. This would enable new changes getting reflected on client immediatly.
When you want to generate conditional JS.
The usage you have specified in example wouldn't probably serve much purpose; would probably just delay the loading of page if processing by server takes time and instead a async ajax call would be much preferred.
Is this correct approach ? its +ves
and -ves.
Depends whether you want to use asynchronous (ajax) way or not. Nothing like +ve or -ve.
The later method takes more time though.
Which are the correct scenarious to
user it?
Ajax way is the correct method there in that sense.
Is this also means that any HTML tag
taking "src" tag can be used like
this?
src is used to specify the source path. That is what it is meant to do.

Categories

Resources