I have this kind of problem, I have iframes with videos embedded into my pages of the website. Note, that iframes urls are from another domain. From time to time these urls can be broken, or stop working and instead of the video there is a message "This video has been removed from public access. ". Is there any way that I can delete those "failed" iframes from the pages by jquery or just javascript.
I was thinking I could be able to search for text inside iframes similar t
$("iframe").each(function() {
var val = $(this).is(':contains("video has been")');
console.log(val); // returns false
});
and then remove those, but it returns false, afa I understood from the http://en.wikipedia.org/wiki/Same-origin_policy.
Also, if it matters, I found out that the difference(without having the above text) between working and broken iframe, is that the last one does not contain object node.
Is there any method to handle this problem ?
Thanks
Due to Same Origin Policy, the browser will prevent all AJAX to different domains and direct access of iframes of different domain. However, there are ways to bypass this limit. One way is to let a server to fetch the data, then return back the data to the client. Here is one plugin for jQuery that does this. It uses YQL (Yahoo Query Language) as a proxy.
Just make a normal GET request with .ajax and the plugin will handle of the details for you:
$.ajax({
url: [url of the iframe],
type: "GET",
success: function(data){
$(data.responseText); //do something with it
}
});
http://jsfiddle.net/DerekL/HGHJ5/
Of course, if you don't trust Yahoo of handling the data, you can always host one yourself.
Related
I'd like to send a request to a simple URL from my JavaScript, so that the base URL will NOT be added to the request URL. For example, the request should be sent to the following URL (without the base URL):
SAPEVENT:SOME_TEXT?2
I used the jQuery's $.ajax function in order to implement it, but without success.
Here is a JSFiddle for it:
http://jsfiddle.net/txb6tdjj/2/
The JS code:
function sendEvent(id) {
$.ajax("SAPEVENT:SOME_TEXT?" + id);
}
sendEvent(2);
I see the following error in the JS console:
XMLHttpRequest cannot load sapevent:SOME_TEXT?2. Cross origin requests
are only supported for HTTP. (jquery-2.1.0.js:8556)
I even set the parameter crossDomain: true, but it didn't help:
http://jsfiddle.net/auhx2v2v/3/
The JS code:
function sendEvent(id) {
$.ajax({
url: "SAPEVENT:SOME_TEXT?" + id,
crossDomain: true
});
}
sendEvent(2);
It ends up with the same error.
It works correct in the HTML like this:
http://jsfiddle.net/1f6npcn2/2/
The HTML code which works correctly:
<FORM action="SAPEVENT:PRESS_ME">
Click on me to send an event!
<INPUT TYPE="submit" VALUE="Press me to send an event!"/>
</FORM>
But I need to implement it in JavaScript, so that a request parameter can be set dynamically in the URL in JavaScript.
Do you know how to implement it in JS so that the request will be sent to the URL SAPEVENT:SOME_TEXT?2 without the base URL?
Additional information about used browsers: The error is shown only in Chrome. IE and Firefox do not show an error, but they also don't send the request.
Additional information for the SAP guys: I know there is a SAP Note 191908 which states that it's impossible, but a colleague has confirmed that he has successfully tested such functionality in an HTML page which used the same code as I copied above (see the HTML code above and http://jsfiddle.net/1f6npcn2/2/). So the SAP Note is wrong. I know how I can implement this functionality in HTML, but I don't know how I can implement it in JS. That's the problem.
I have no experience of working with SAP but I think you are missing a crucial part here.
In the samples you gave SAPEVENT:CLICK_ON_ME isn't a http url at all but rather it would invoke whatever handles the SAPEVENT-protocol on the local computer with the parameter CLICK_ON_ME. I'm guessing that you have some sort of client installed on your computer that does this for you (how do I create my own URL protocol? (e.g. so://...) contains some more information on how this is accomplished).
The reason your error-message talks about crossdomain-stuff is probably because it tried to interpret it as host:port.
So in other words, since this isn't a http url there isn't a webserver working on the other end so you can't do ajax-requests against it.
The SAPEVENT: stuff is not handled by any web server. The SAP GUI uses an embedded Internet Explorer and registers a custom protocol handler. There is no use in trying to use ajax techniques since you need to reach the container of the client, not the server. To reiterate: You do not want to "send a request" anywhere, you want to convince the browser that a certain local navigation event happened". SAP Note 191908 contains more information on that topic.
No idea about SAP Views, but to me this seems like a usual behaviour on webservers. I presume that SAPEVENT gets parsed by the server during the runtime to a more regular URI. Only the views get parsed, not the resources like CSS and JS, so the SAPEVENT placeholders in the JS file don't get parsed and the JS interpreter will not accept it as a valid URI. One of the common ways of solving this, is to create either a hidden form in the HTML or just a hidden input containing the server-generated values you are needing. For example
SAP View:
<input type="hidden" id="my_event_url" value="SAPEVENT:PRESS_ME">
JS:
function sendEvent(id) {
$.ajax({
url: $('#my_event_url').val() + '?' + id,
crossDomain: true
});
}
sendEvent(2);
I finally implemented it in JavaScript. Thanks go to this web page.
I modified the solution which was shown in this web page in order to add a link instead of a form in JavaScript.
This is the working solution in JS:
var targetUrl = "SAPEVENT:SOME_TEXT?2";
function sendSapEvent(targetUrl) {
var link = document.createElement("a");
link.setAttribute("style", "display:none;");
link.setAttribute("href", targetUrl);
// Move the click function to another variable
// so that it doesn't get overwritten.
link._click_function_ = link.click;
document.body.appendChild(link);
link._click_function_();
}
sendSapEvent(targetUrl);
You can find it also in this JSFiddle: http://jsfiddle.net/708r95p0/6/
It works! It sends a request to the URL sapevent:SOME_TEXT?2
I decided to use a link instead of a form element, bacause I couldn't pass the request parameter using a form.
How to not copy my source code to other servers and provide them with a JS or iframe like the analytics and statcounter provide us?
I wrote a PHP script with JS that in it's basic description goes like this:
When someone visits my website, gets a cookie with a value of a unique identification and at the same time using AJAX I make some checks and I save that same value to mysql accordingly. After this, if he visits again my site, (in most of the cases) a cookie is not created again.
In depth:
The cookie value is created with JS and I want to keep it that way for future enhancements.
My code (index.php, add-to-mysql.php) has JS and PHP.
I want to use this script in my additional domains, and some of them are in different server. But I don't want to put all my source files to there accounts.
The ideal for me is to provide them with a JS code, like the google analytics or statcounter give us (or alternative similar ways), an iframe... solutions like these.
When a visitor gets into their page, my mySQL in a remote server (my server) will be updated and a cookie will created on their site. Transferring data from and to.
Is this something possible to be made? If yes, how can I start studying for this? Can you provide me with some guidelines?
Thank you.
this is a block of code, the ajax function that posts the random number to the add-to-mysql.php file where i make some actions
$.ajax({
type: 'POST',
url: 'add-to-mysql.php',
data: { one: hash }, //an antikatastiso to hash me to a ke kano to md5 meso php sto ajax vgenei to idio
success: function(data) {
alert("success! X: " + data);
}
});
It seems to me you have three options here.
1. Use JSONP
JSONP allows you to do cross domain ajax calls so that you can just call in to your home server from your other domains without being obstructed.
This is probably the easiest route to go I'm thinking.
See here for a quick write up on how JSONP works:
https://stackoverflow.com/a/2067584/867294
jQuery supports jsonp so it's not to difficult to get started with:
http://learn.jquery.com/ajax/working-with-jsonp/
JSONP works by dynamically adding a script to the document that then calls a callback.
The contents of ths javascript file need to be generated by the server, your PHP file add-to-mysql.php will have to echo out something like this:
<?= htmlspecialchars($_GET["callback"]) =>('someData you want to return');
You can access the one: parameter that was passed in from jQuery trough the $_GET array as well, as this is just a GET request.
From the client side you can call this route like so:
Note that this will always be a GET request, all parameters will go trough the URL.
The 'callback' parameter is the connecting factor here, it makes sure the PHP side knows what JavaScript function to generate.
$.ajax({
jsonp: 'callback',
dataType: "jsonp",
url: 'http://my-server.com/add-to-mysql.php',
data: { one: hash }, //an antikatastiso to hash me to a ke kano to md5 meso php sto ajax vgenei to idio
success: function(data) {
alert("success! X: " + data);
}
});
2. Use CORS
CORS will allow you to make ajax calls to a different domain then the one where your JS is running. This does however require you to send special http headers from the serving html page, so this does require you to modify the servers.
See here for a qucik intro on CORS:
http://www.html5rocks.com/en/tutorials/cors/
In short, the headers you will need to set from the serving html page are:
Access-Control-Allow-Origin: http://domain.com
Access-Control-Expose-Headers: list,of,headers
3. Posting to an iFrame
Posting trough a hidden iFrame is also an option.
For this you need to set the target of a form to the name of the iframe, the advantages here is that you can use POST as well. You can submit and populate the form trough jQuery as well.
$('#one_input').val('someHash');
$('#myForm').submit();
You can just put everything in a hidden div if you don't want to show it on the page:
<div style='display:none;'>
<form id="myForm" action="http://my-server.com/add-to-mysql.php" method="post" target="my_iframe">
<input type="input" id="one_input" value="" />
</form>
<iframe name="my_iframe" ></iframe>
</div>
You could also just set the url of the iframe with your parameter if you don't need any feedback.
var hash = 'stuff';
document.getElementId('one_input').src="http://my-server.com/add-to-mysql.php?one=" + hash;
Extra
you could also use the iframe with Window.postMessage
Building on the previous example:
$('#my_iframe')[0].contentWindow.postMessage('hash', 'my-server.com');
But this requires you to have already a page loaded in your iframe that will then receive the message trough JavaScript, so I don't think this is what you are looking for.
Google Analytics provide an script that doesn't post data, it loads an script asynchronously (this is very important to avoid messing with load times of the original website), then it sends all of their info requesting for a .gif image. Your code should do a request to an url ending in .gif, with all the data in GET form. Do your magic and return a gif with size 1px*1px and no content.
Just request something like this
yourdomain.com/a.gif?cookie=1234aqfajsdlq....&uid=qekjlajdfa
Put all your data in there
I recommend obfuscating it a bit, but that should help you avoid cors, iframes or jsop
EDIT
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'id', 'domain');
ga('send', 'pageview');
</script>
This was taken from GA. See that it creates a tag, with the async attribute to avoid load time issues (remember sync scripts stop the page rendering). Then it creates and array where it pushes all the info it needs in tuples. It defines ga in the window as a function that pushes all its arguments to a q.
The you can create an script that takes all of the data you need, with js, cookies, domain, etc. and send to the server.
For example, you want the domain that the user is visiting:
//You won't have jquery, but you get the idea
//Create a tag
var i = $('<img>').prop('src', 'yourdomain.com/a.gif?domain' + window.location.origin).css('display', 'none');
$('body').append(i);
In some point you will have to set a cookie. I thing cookies can't not be cross domain, so you should set them in your requests not in js.
On the server side you check the cookie, if there is none, you created, and there you can track many things.
Afterwards, your script can check for cors support, and use ajax without this. I don't recommend JSONP, is very error prone, and is actually kind of a hack
In order to avoid the cross-domain problematic you can include an iframe at the other sites, that loads from your site. It creates its own scope (domain) and you can freely use ajax from inside communicating with your site.
However, if you set cookies there, it will be associated to the iframes source domain (your domain). This might or might not be a problem. Note, that this can be used to identify users across all the other domains including this same iframe (from your domain).
Is it possible to:
From within my webpage, get all the HTML source from another webpage. I need to do this in order to pass that other pages html source to my function.
The following different attempts don't work:
var html = $.get("http://simplyrecipes.com/recipes/braised_turkey_legs/").html();
var html = $.get("http://simplyrecipes.com/recipes/braised_turkey_legs/");
var html = $("http://simplyrecipes.com/recipes/braised_turkey_legs/").html();
Using Ajax, and get is just a shortcut for ajax, it's not really possible to get the source html from other domains, if that is what your trying to do? as ajax has a same origin policy for security reasons.
However going thru YQL it is possible to do is, read this to see how, or you could proxy with php or something else, with just regular get requests however it's not doable.
If the pages you are trying to get are on your domain, .load(); would probably be better.
Javascript has a same origin policy, this is what's holding you back.
jQuery's get function does not return the loaded data - rather, it calls a callback function and passes the data as a parameter.
This is from the documentation:
$.get('ajax/test.html', function(data) {
$('.result').html(data);
alert('Load was performed.');
});
P.S.: Note that in any case this will only work on the same domain, as cross-domain AJAX is normally not supported for security reasons.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Load website into DIV
Hey all i am trying to find a way to call an external website and retreve its HTML so that i can check for something in it (wither the user entered a valid VIN # or not depending on what this website calls back)
This is the code i have:
$.ajaxSetup ({
cache: false
});
$("#load_callback").click(function(){
$.ajax({
url: 'http://www.google.com',
dataType: 'text',
success: function(data) {
alert(data);
}
});
});
It works but only if i have it pointed to my server (and running on my server also). Is there a way i can call an external website using jquery/ajax? I am aware of the Same origin policy but was hoping something like what i want to do did not fall into that catagory?
I cant even get an iFrames title? Really??? wow....
David
You need to use jsonp: http://en.wikipedia.org/wiki/JSON#JSONP
These links should explain it:
http://www.remysharp.com/2007/10/08/what-is-jsonp
http://www.ibm.com/developerworks/library/wa-aj-jsonp1-
The other option you have is to write your own server-side proxy to it, i.e. have a page/controller/handler on your server that passes your request through and returns the result. It won't be as fast as going direct, and it will increase your site's traffic, but it will get you around the security problem.
Stick to simple things, if you want to load websites, be simple and go with iframe. If you want to make request use PHP or similar. For example you can use curl method to make request to another websites through PHP. Or even simpler, setup a form to request to another web server.
I've written some HTML/Javascript that sits on a third-party server for security reasons. This page performs a javascript post to another page on the same site. However, instead of responding with useful data, it instead wants to perform a redirect (if you would post via a normal HTML form to this page, it would redirect your browser). How can I process this process? I basically want to be able to extract the url's query parameters that it is trying to redirect with (and then put this link into a hidden form field).
Here is my basic ajax post...
$.ajax({
url: '/someurl/idontcontrol',
data: serialized_form_data,
async: false,
type: 'POST',
success: function(data, textStatus, x) {
alert(x);
alert(x.getAllResponseHeaders());
return false;
$('#redirect_link').val(WHAT_DO_I_PUT_HERE);
}
});
Note that the URL I am posting to is not one that I control, so I have no power over what it returns.
UPDATE: When I use the above alerts, I receive "[object XMLHttpRequest]" and "null". I'm monitoring the headers with a Firefox plugin and they seem be coming back as expected, but I can't seem to access them via javascript (I've also tried x.getResponseHeader('Location'), but that and all other calls to getResponseHeader return empty).
ALSO: I don't know if it matters, but the status code is 302 (as opposed to 301 or 303).
Thanks!
According to the jQuery Documentation the success method can take a third argument which is the XMLHttpRequest object.
According to Mozilla's XMLHttpRequest page, this object should have a "status" property. If you check the value of this property, and it is a redirect code, such as 301 (permanent redirect) or 303 (temporary redirect) it is known the processing page is trying to perform a redirect. The "statusText" property should be able to be used to determine the location it is trying to redirect you to.
If you know it is trying to redirect, you can then re-post the data through Ajax to the new URL.
The strange thing is though, when researching this, stumbled across this page that indicates the XMLHttpRequest object should follow redirects (see the comments). So it seems like this would be a non-issue.
Unless the processing page is using an HTML meta redirect (like below) to do the redirection. In that case, I'm not sure what could be done - maybe try to parse the returned HTML for meta tags and see if any of them are attempting a redirect.
<meta http-equiv="refresh" content="0;url=http://www.example.com/some-redirected-page">
You can't get the full HTTP headers from an AJAX call in JQUery, so you can't process the redirect in this way.
However with a raw javascript request you do have access to the XMLHttpRequest getAllResponseHeaders() method which will allow you to process the redirect (this function for single headers).
Sorry, not directly an answer to your question, but I'm sure it's possible with jQuery too as it's quite simple with Prototype.
// Warning: this is Prototype, not jQuery ;-)
//...
onComplete: function(response) {
var refresh = response.getResponseHeader("Refresh");
var whatever = response.getResponseHeader("Whatever");
}
//...