I'm trying to do my own bookmarklet and I already tried to read some response in SO but nothing to answer the weird reaction I got from my script.
I'm doing an AJAX call from my bookmarklet, so I do the little trick :
var newScript = document.createElement("script");
newScript.type = "text/javascript";
newScript.src = "http://example.com/urlToMyJS.js";
document.body.appendChild(newScript);
void(0);
And the urlToMyJS.js is like this :
var u = 'http://example.com/scriptToCall.php';
var request = new XMLHttpRequest();
request.open("GET", u, true);
request.onreadystatechange = function() {
var done = 4, ok = 200;
if (request.readyState == done && request.status == ok) {
if (request.responseText) {
alert(request.responseText);
}
}
};
request.send(null);
The weird part is :
The javascript is always launched and scriptToCall.php is always called too (it logs every hit)
The alert shows the responseText when I click on the bookmarklet on example.com
Sometimes, on other sites, the alert shows nothing (but still appears)
Some other times, the alert doesn't even show... (but I still have the log hit...)
Do you have any idea why it does that? And if yes, do you have any idea how I could make it always show the responseText?
status won't be ok unless you are testing the bookmarklet on your own site (example.com).
When you run the bookmarklet on a different site to example.com (which is after all the whole point of having a bookmarklet), it will be doing a cross-origin XMLHttpRequest to example.com. Depending on what browser you're using, that might do the request, but you won't be able to read the response due to the Same Origin Policy. It's an essential security feature that you can't make user-impersonating XMLHttpRequests to other servers.
If you want to make an XMLHttpRequest back to your server, you must do it from a document on your server, typically by having the bookmarklet create an <iframe> pointing to example.com.
Alternatively, use JSONP (<script> inclusion) to call scriptToCall.php.
Well, finally, I used another trick :
var newScript = document.createElement("script");
newScript.type = "text/javascript";
newScript.src = "http://example.com/scriptToCall.php";
document.body.appendChild(newScript);
void(0);
This way (the PHP is sending a javascript header), no more AJAX. It was nonsense in my case since both file were in the same server/folder, 1 movement instead of 2!
Anyway, thanks bobince for all the details I might use in the future !
Related
I'm building a website where people can leave comments on each event created by me. Each event has its own page eg. showthread.php?t=1, showthread.php?t=2 and so on..
I managed to create a comment section for each event but I got a problem with loading comment for each event. I used $_SESSION['id'] to pass the $_GET['t'] value to another php script
My code is like this:
showthread.php
$id=$_GET['t'];
$_SESSION['id']=$id;
main_function.php
$thread=$_SESSION["id"];
SELECT * FROM comment WHERE thread='$thread' ORDER BY timestamp DESC,
these codes are working fine but I need to refresh the page in order to load the right comment for each thread, is there a way for me to load it properly without refreshing each time I load an event? thanks in advance!
AJAX is javascript used to make requests to the server. You can use it to change your page without refreshing.
Learn more here.
An example of what it looks like:
//create the request object
var xhttp = new XMLHttpRequest();
//activates when you hear back from the server
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
//xhttp.responseText is filled with what we get back from the server
document.getElementById("my-element-thing").innerHTML = xhttp.responseText;
}
};
//Type of request, url you're sending to, asyncronous
xhttp.open("GET", "www.google.com?p=myparam", true);
//Send your request to the server
xhttp.send();
Edit: The idea is you would also build a PHP page to accept this request. PHP would analyze it and then echo a response. Be sure that the PHP only contains what you want and nothing else (no tags etc).
Have you tried to use javascript AJAX?
https://www.w3schools.com/xml/ajax_intro.asp
I have this bit of java script that is just grabbing an ID off a website and passing it to another php script on a seperate domain:
javascript is on:
https://myspot.com
and is going to
http://theotherwebsite.edu
This was more or less working, I had to work a previous cross site solution that now seems not to be honored on firefox 23 and IE10.
The previous solution was using something like this:
var isIE10 = false; //this is beacuse stupid IE10 now does not work with the window.XDomainRequest
/*#cc_on
if (/^10/.test(#_jscript_version)) {
isIE10 = true;
}
#*/
console.log(isIE10);
var isIE8 = window.XDomainRequest ? true : false;
var invocation=createCrossDomainRequest();
function createCrossDomainRequest(url, handler)
{
var request;
if ((isIE8) && (!isIE10)) //tried to hack my own isIE10 fix didnt work
{
request = new window.XDomainRequest();
}
else
{
request = new XMLHttpRequest();
}
return request;
}
function callOtherDomain()
{
if (invocation)
{
if("withCredentials" in invocation) //was taking a stab in the dark with this.
{
invocation.onload=outputResult;
invocation.open("GET", url, true);
invocation.send();
}
else if(isIE8)
{
invocation.onload = outputResult;
invocation.open("GET", url, true);
invocation.send();
}
else
{
invocation.open('GET', url, true);
invocation.onreadystatechange = handler;
invocation.send();
}
}
else
{
var text = "No Invocation TookPlace At All";
var textNode = document.createTextNode(text);
var textDiv = document.getElementById("textDiv");
textDiv.appendChild(textNode);
}
}
function handler(evtXHR)
{
if (invocation.readyState == 4)
{
if (invocation.status == 200)
{
outputResult();
}
else
{
alert("Invocation Errors Occured " + invocation.status + " state: " + invocation.readyState);
}
}
}
function outputResult()
{
var response = invocation.responseText;
//get JSON of response
var obj = JSON.parse(response);
var mtype = obj.messagetype;
var output = obj.message;
var url = obj.url;
if(mtype=="error")
{
parent.location=url;
}
else if(mtype=="warning")
{
var answer=confirm(output);
if(answer)
parent.location=url;
}
//var textDiv = document.getElementById("textDiv");
//textDiv.innerHTML += response;
}
callOtherDomain();
So I am not sure what is going on here, I get on firefox 23 an error in the console:
Blocked loading mixed active content "http://theotherwebsite.edu"
I know this is because the main script is loaded on https, vs http. But it was not caring before. I also am aware of this error puts a shield up in the address bar of firefox where the user can tell it to enable the blocked content. This is not an acceptable solution for me. Also if i put my silly little php script under https, that is a certificate I need too?
Then IE10 just doesn't work:
SCRIPT5: Access is denied.
landing, line 64 character 421
So I am not sure what I need to do to get my code working again, having the user adjust the browser isn't feasible cause this is distributed enterprise wide, it was for a nag screen to let them know to change their password based on some ldap entry that the php file accesses with the ID passed from the website via ajax.
I was doing some googling but found nothing, most I found was the php handle to make the website I guess CORS compatible:
<?php
header('Access-Control-Allow-Origin: *');
Which I implemented originally as well. So not sure what to try or where to look next? It is a simple JSON string that comes back, can I try the preflight method as described here:
http://ppe.blogs.msdn.com/b/ie/archive/2012/02/09/cors-for-xhr-in-ie10.aspx
??? if i do I am not sure what the headers should look like.
I was going to post the firefox 23 response header but it never makes the request as it straight up blocks the loading mixed active content. So I guess I have two issues to contend with, one that the javascript lives on https and makes a call to http...this might be my only issue in firefox, not 100% sure if i would have cross site issues.
IE10 the network request header is never find and I am looking inside the F12 key pressed area in IE10, under network and I click start capturing before I load the page with the xhr call.
So I guess I am asking what changed in firefox23 and IE10 to not let my code work anymore?
Firefox 23+ will block what they call "active mixed content". That is: Content hosted at a non-secure (http) location that is requested from a secure webpage (https). "Active" in this context essentially means everything that is not a media type (not an image, audio or video resource). This is to prevent man-in-the-middle attacks that would use non-secure sub-requests to get into secure pages.
For more information see the Mixed Content article on MDN.
As the request is blocked before even hitting the network, there won't be any response headers/data.
Not sure about IE10, but their documentation seems to indicate they block such requests for the same reasons, saying:
Cross-domain, cross-port, and mixed protocol requests are not allowed.
It may sound odd, but I've been programming games in PHP. The main problem I've found was that the only way to update PHP is to load a page. That makes real-time slow. Javascript can interact with a page without reloading it. Is it possible to load PHP pages on a page using Javascript? So that it would allow PHP to be loaded over and over without reloading.
I've seen it done with Chat rooms but not sure how it works.
We mostly use Ajax, which consists in a client-side Javascript code that calls a server-side page, with out leaving the page.
Here's an example that will get the displayed content of a page, using the GET method (JSFiddle):
var xhr = XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHttp');
xhr.onreadystatechange = function(){
if(xhr.readyState==4 && ((xhr.status>=200 && xhr.status<300) || xhr.status==304)){//Checks if the content was loaded
console.log(this.responseText);
}
}
xhr.open('GET','myPHPPage.php?foo=foo&bar=bar',true);
xhr.send();
And here using the POST method (JSFiddle):
var xhr = XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHttp');
var data = 'foo=foo&bar=bar';
xhr.onreadystatechange = function(){
if(xhr.readyState==4 && ((xhr.status>=200 && xhr.status<300) || xhr.status==304)){//Checks if the content was loaded
console.log(this.responseText);
}
}
xhr.open('POST','myPHPPage.php',true);
xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
xhr.setRequestHeader('Content-length',data.length);
xhr.send(data);
Note that here we use the setRequestHeader method to change the headers of this HTTP request and, in this case, to change the Content-type and the Content-length (this header has a default value of 4096 bytes). Also, the setRequestHeader method must be called after the open method.
These links should help you:
https://developer.mozilla.org/en/Ajax
http://code.google.com/intl/pt-BR/edu/ajax/tutorials/ajax-tutorial.html
Yes it's incredibly common.
Read up on Ajax.
We call that AJAX!!!
Just Read The documentation on internet about ajax
I write my scripts in PHP, and there are HTML and javascripts inside. What I want is when I click a button(in HTML), it calls a javascript function, the function should visit a url like "http://localhost/1/2" And the page stays as before. Is it feasible?
I just want it work, no matter in js or php. Thanks.
Since the page is on the same domain, you may use an Ajax request:
var request = new XMLHttpRequest();
request.open("GET", url, true);
request.send(null);
Note that this does not do any error-checking, however. If you need that, there are a multitude of available tutorials easily found with a search.
And since you ask, for pages not on the same domain, using an <iframe> is sometimes possible:
var frame = document.createElement("iframe");
frame.src = url;
frame.style.position = "relative";
frame.style.left = "-9999px";
document.body.appendChild(frame);
This is commonly known as AJAX (being able to send a request to the server and receive a response back without navigating away from the page).
AJAX is supported in ALL modern browsers, but sometimes there are inconsistencies, so it is best to use a javascript framework such as JQuery, YUI or another framework.
I tend to use YUI, so here's a quick example on how to send an AJAX request using YUI. This uses the IO Utility:
// Create a YUI instance using io module.
YUI().use("io", function(Y) {
var uri = "http://localhost/1/2";
// Define a function to handle the response data.
function complete() {
Y.log('success!');
};
// Subscribe to event "io:complete"
Y.on('io:complete', complete);
// Make an HTTP request to 'get.php'.
// NOTE: This transaction does not use a configuration object.
var request = Y.io(uri);
});
Is it possible? Now, I have done live chat, where with jquery's help I connect to .php file and check last modified time and if it is not as before, I retrieve messages. If it were possible in javascript I probably would save a lot of resources.
Thanks.
It's definitely possible if the server is sending an accurate Last-Modified header for that particular file:
var getMTime = function(url, callback) {
var xhr = XMLHttpRequest();
xhr.open('HEAD', url, true); // use HEAD - we only need the headers
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
var mtime = new Date(xhr.getResponseHeader('Last-Modified'));
if (mtime.toString() === 'Invalid Date') {
callback(); // dont want to return a bad date
} else {
callback(mtime);
}
}
}
xhr.send();
};
getMTime('url here', function(mtime) {
if (mtime) console.log('the mtime is:' + mtime.toISOString());
});
Short answer: there's no way but AJAX + a server-side script (in your case, jQuery + php)
Being a client-side script, javascript gets run on the client's computer, so if the file whose m-time you want to check is on the server, then you are correct to use AJAX and a server-side script. No other way will work.
If the file whose m-time you want to check is on the client's computer, then you're out of luck. Javascript is intentionally designed to be prevented from accessing the client's files. (It can only access cookies, which are on the client's computer, however, because the browser (not any javascript) loads those into its work environment.)
Maybe HTTP ETag headers could be used to check if the page has changed. The first response contains ETag and your client uses that for the following request. Your PHP server side code would then send 304 if the page has not been modified.
http://en.wikipedia.org/wiki/HTTP_ETag