I have an ajax script which references something in the same domain. I want to pass some HTML and then javascript associated with it. I figured that since it is not X-domain, It might let me do that. My goal is that I am taking a webservice and then returning a string which will be put into a div... when the javascript is inserted it would be fired, which allows a bunch of good stuff to happen.
I was wondering if there is anything special i need to do to pass javascript from the server across this request. My current AJAX request seems to sanitize and remove the scripts. THoughts? How would i go about this?
If you want script to be included in the AJAX response and executed by the browser, you will first need to do something similar to the article posted as a potential duplicate, excepting that you have HTML to be injected as well. Proceed injecting it as normal, but after you set the content, try something such as:
$(responseText).find("script").each(function(index, element){
var script = $(element).text();
eval(script);
}
Untested
However, I would try to find a way to avoid doing the above. JQuery provides ways to handle classes of elements added dynamically to the DOM. See: http://api.jquery.com/on/
Related
today when I exploring Google API, I saw in their sample code, they simply request a url by doing
<script src="src="https://www.googleapis.com/customsearch/v1?key=AIzaSyCVAXiUzRYsML1Pv6RwSG1.."></script>
Sad for me, my first thought before seeing this was ajax. Now I'm confused, the different with this 2. I can't do request as above as I need to add users' input within it.
like
"https://www.googleapis.com/customsearch/v1?key=AIzaSyCVAXiUzRYsML1Pv6RwSG1&"'+user+'"
so if I use ajax, will achieve the same? sorry that I haven't try, but I'm still in confusion what's the diff btw them even I try.
Using <script src> to retrieve JSON data is a technique called JSONP. It gets around cross-site scripting limitations (your browser may block an AJAX request if it's to a different domain than the page it comes from; it won't block a script load that way). The disadvantage is that you can't do other HTTP methods (PUT, POST, DELETE, etc) - only GET. Also, as #FelixKing pointed out, the server has to support it - if you just drop a JSON blob as the contents of <script> element, that's not going to do you any good - it has to be sent to a callback. If the API supports JSONP, it will usually take a callback=functionName parameter, and the emitted script will be functionName({... JSON blob here ...}).
You can still make it dynamic to add things like your user parameter, however. You just need to use Javascript to add the <script> element to the page, instead of hard-coding it into the HTML:
var user = "someone";
var scriptTag = document.createElement('script');
scriptTag.src =
"https://www.googleapis.com/customsearch/v1?key=AIzaSyCVAXiUzRYsML1Pv6RwSG1&user="+user
document.getElementsByTagName('html')[0].appendChild(scriptTag);
But I don't know what you're doing exactly, or if that call even supports JSONP; that's just an example of using Javascript to dynamically add a <script> element. Details are up to you.
Ajax will acchieve the same if you do something like this:
$.get("https://www.googleapis.com/customsearch/v1?key=AIzaSyCVAXiUzRYsML1Pv6RwSG1&"+user, function(response) {
// process the result here
});
As additional note: the "<script src=https://www.googleapis..." thing is a method used by ajax implementation if other methods fails (XMLHttpRequest, for example), so, you can (should) relay on ajax a let the library do what is better for your context (this is good for cross-browser support)
I'm pretty new to AJAX so forgive me if this is a dumb question:
I would like to update a div with the content of a php-file which lies within a protected folder so it only can be included within a php-file but not adressed from the browser.
Since JavaScript is client-side this would mean I couldn't call it, right?
For example I got my index.php with the following code (jQuery included):
<script>
$("#content").load("includes/login.php");
</script>
Where #content refers to a div. This works fine but as includes should not be accessible it becomes problematic.
Then I thought I could put something like a "wrapper.php" in the accessible area which then includes the specific php-files depending on which variables you give it.
Is this the correct way to approach this or am I doing it wrong?
I think the idea of a "wrapper.php" is right. If you want to use it for many files you could do something like this, checking if it is an AJAX call to prevent direct load of the file:
// wrapper.php
<?php
// Check if it is AJAX
if (isset($_SERVER['HTTP_X_REQUESTED_WITH'])
AND strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest') {
$filename = $_GET['f'];
include 'includes/'.$filename.'.php';
}
And then:
$("#content").load("wrapper.php?f=login");
But be carefull with this, because it may be insecure.
If you want to be lazy, you could just load the entire page via load and parse the content to fetch #content
jQuery will split the argument by the space and use the second element as a selector for the entire page content.
$("#content").load("full/path/to/login #content");
No haters, I said it's a lazy method.
I'm trying to interface with Adobe Test & Target because I want to load JSON rather than markup through my mbox. I want to load some mbox content into javascript and manually add it to the DOM. I have searched all over for full documentation of the mbox.js but I can't find anything other than the very basics. It describes how to use mboxDefine() and mboxUpdate to target a specific dom element. Is there a function that just returns the content?
```
T&T does not offer a function to assign the response to a javascript variable. Basically the way it works is mbox.js builds a url to their server and then then outputs a script include tag. This is done to get around the same origin policy limitations (cross-site scripting).
In order to handle whatever is in the html offer, they put it in their own javascript variable on their server and then output it as that as the response. However, they also have the response output the code that updates the target element. So there's nothing you can do to actually stop them from updating the target element with the html offer contents. They simply don't expose that.
However, you don't have to put html in an html offer. You can put json (javascript) in an html offer. Just do like
html offer 'myJsonMbox' (in interface)
<script type='text/javascript'>
var myJsonString = "[json string]";
</script>
Then on your page (inside your body tag, but before your code that wants to use it) you'd have the regular mbox code:
<div class='mboxDefault'></div>
<script type='test/javascript'>
mboxCreate('myJsonMbox');
</script>
And then somewhere after that, where you're wanting to do something with it, that myJsonString is there for you to reference. Or, you can do it with the mboxDefine and mboxUpdate sometime after page load, if you prefer.
Is there some particular reason why you don't think this will work for you?
You can:
a- Insert JS code you are going to use to manually manipulate the DOM
b- Insert CSS code you can use to alter the original HTMl or the newly added HTML.
c- Insert a call to a 3rd party script that will load content from a 3rd party server if needed, or the same server.
Through a Javascript request, XMLHttpRequest responds with some additional Javascript that needs to be added to the page the requesting page.
Using eval(), if the response is something like:
alert('This is the js response');
... then this works just fine.
However, the text returned could look something like this:
<script language="javascript">var checkVar='checkVar: value 1';</script>
but most likely:
<script src="http://www.somesite.com/setCheckVarValue.js"></script>
... where additional JS needs to be loaded on the page.
I have ensured that the XMLHttpRequest is synchronous, as I want to reference checkVar right after this.
So:
<script type="text/javascript" src="http://www.mysite.com/addJSToPage.js" />
// at this point, since this is a synchronous call, page processing waits
// until the response is received that needs to include the additional JS
// to load; this, for testing sets the value of checkVar
<script type="text/javascript" >
alert(checkVar);
</script>
The alert message should read "checkVar: value 1".
For other reasons, this is not just as simple as setting var checkVar in addJSToPaged.js, so I'm not looking for that kind of recommendation.
I'm using alert(checkVar) simply as a test to ensure that a value has been set through JS in the response.
I suppose that I could strip out the beginning and ending script tags and keep the eval() way of doing it. However, I would like to know if there are any solutions that support what I'm looking for?
Thanks.
UPDATE
Following Prashanth's suggestion, in addJSToPage.js I added:
var dynamicElement = document.createElement('div');
Then in the response from the XMLHttpRequest, I did:
dynamicElement.appendChild = xmlhttp.responseText;
Still not seeing the value of checkVar.
Ignoring the fact that whatever you are doing is probably a bad idea, Prashanth has the right idea of inserting it into the DOM. you could also strip out the tags and just eval as "normal".
Not ignoring the fact that 1) eval is evil, 2) dynamically loading remote code is bad and 3) synchronous AJAX is extra bad, I have this to say:
Unless you know what you are doing, evaling anything is a bad idea, its hard to debug, can expose massive security flaws and all sorts of other nasties. You then compound this by loading remote code, which is apparently generated in a way outside of your control because you aren't able to get just the script. Synchronous Ajax is bad because there is only one thread in javascript, blocking on Ajax will literally lock up the entire page until it is loaded because even things like scrolling generate javascript events, which the currently busy engine has to check for handlers. While the request goes fast on your local machine, someone with a slow or poor quality connection could be waiting a while, up to the timeout time for the connection. The 'A' in AJAX is asynchronous, and for a good reason, use the callbacks, they are there for a reason.
If you are just doing data passing, use JSON, which is JavaScript Object Notation, a simple data format that happens to also be valid JavaScript. You can use eval on it, but I suggest a JSON parser, i think most modern browsers have them built in (could be wrong here). JSON is good because it can express complex data structures, is simple to generate and parse and is widely supported.
Recapping - the need is present to be able to dynamically load some content onto a page after/during load, and have it execute. By execute, I don't just mean change the text on some div - that's easy. But if we want to load some new JS dynamically, say an alert that comes from some outside source, and inject it, along with it's script tags, and maybe some other HTML code, then the solution is to use the following jQuery call:
jQuery(dynamicResponse).appendTo('body');
dynamicResponse comes from an asynchronous $.ajax({}) or XmlHttpRequest response. Once present, it is appended onto whatever DOM element, specified in appendTo() and executed.
Here is the example
var script = document.createElement("script");
//innerHTML can be the response from your server. But send the text with script tag.
script.innerHTML = "var foo = function(){console.log('injected into the DOM')}"
document.body.appendChild(script) // insert into the DOM
foo() // call the function
I have a script element in my webpage, something like this:
<script id="myscript"></script>
Now, from a javascript file, I'm doing something like the following:
$('#myscript').src('http://foo.bar?callback=somefunc')
Now this remote script 'returns javascript' of the following form:
somefunc(somearg);
When I run all of this, things work neatly, the script gets loaded dynamically, and the 'somefunc' callback is executed.
The problem happens when I do the same thing again. Let's say I again call the same thing:
$('#myscript').src('http://foo.bar?callback=somefunc')
This, for some reason, DOESNT return the javascript call in Firefox only. (Works fine in IE - somefunc gets executed again as expected).
I can think of ugly workarounds (such as doing a $('head').append('<script...')) every time - but I'd like to know what's going on here.
Thanks in advance!
I would recommend you to use $.getScript instead of using a single script tag load scripts multiple times:
$.getScript("http://foo.bar?callback=somefunc");
That function will abstract the script element creation and its introduction to the DOM.
But it seems you are accessing a JSONP service, in that case you need only $.getJSON:
$.getJSON("http://foo.bar?callback=?", function(json){
// callback
});
I can think of ugly workarounds (such as doing a $('head').append('
Ugliness is subjective; personally, I find the technique you're trying to use (making a single script tag load multiple scripts) far uglier.
But that's not really important. Adding a new script tag works - so if you're having trouble with what you're doing, just use the normal method and live with it.
FWIW: Firefox probably doesn't respond because you're not actually changing anything... If you want to make this even uglier, append some do-nothing querystring parameter that changes each time through.