How to send data from outside site to my server via AJAX? - javascript

I am written the bookmarklet, which takes pictures and videos from a site and must send it to my server via AJAX. The problem is in crossdomain AJAX request - I have got an error:
XMLHttpRequest cannot load http://mysite.com/community/bookmarklet/. Origin http://www.some-nice-site.com is not allowed by Access-Control-Allow-Origin.
How to solve data sending to my server from third-part sites?
Note: I use only plane javascript, this is the stipulation of development.
my code:
function getXmlHttp(){
var xmlhttp;
if (typeof XMLHttpRequest!='undefined') {
xmlhttp = new XMLHttpRequest();
} else {
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (E) {
xmlhttp = false;
}
}
};
return xmlhttp;
};
function vote(data) {
var req = getXmlHttp();
req.onready = function() {
if (req.readyState == 4 & req.status == 200) {
alert('OK');
}
}
req.open('GET', 'http://mydomain.com/community/bookmarklet/');
req.send(JSON.stringify(data()));
};
function dataProcessing(){
//some processing
return data;
};
// I tried it, but not deeply understand.
function JSONPresponse(){
document.getElementById('popup_body').innerHTML = 'done!';
};
(function(){
function pasteIt(){
// this function is builds the form, which get data for dispatch to my server.
};
pasteIt();
document.getElementById('my_button').addEventListener('click', function() {vote(dataProcessing)}, false);
}());

It is quite clear... the site you are attempting is prohibiting connection from outside world. You can try by modifying your http headers in request. See:
Access-Control-Allow-Origin Multiple Origin Domains?
Cannot properly set the Accept HTTP header with jQuery

As #jakeclarkson told - JSON-P is the solution, not the only, but useful for me.
XMLHttpRequest is not needed anymore. Instead it vote(data) function creates the script to build URL with params:
function vote(data) {
var script = document.createElement('script'),
data = JSON.stringify(data());
script.type = 'text/javascript';
script.src = 'http://mysite.com/api/bookmarklet/?vids='+encodeURIComponent(data);
document.getElementsByTagName('head')[0].appendChild(script);
};
The script is fulfilled, so URL is called and params already in the server.

Related

IE11 prompts authentication window on XML HttpRequest

I am running into an issue. The exact same request responds with 401 when sent from IE11.
The endpoint to which a request is sent is a WCF service for uploading a file.
I should probably mention that cookies are not an issue here.
The following is the code that is making the request:
var formData = new FormData();
formData.append('file', upload.file);
formData.append('secure_id', getCookieValue("SecureID"));
var oReq = new XMLHttpRequest();
oReq.open("POST", this.fileUploadUrl, true);
var self = this;
oReq.onload = function (oEvent) {
if (oReq.status == 200) {
upload.status = self.$root.uploadStatusEnum.DONE;
upload.message = self.$root.humanFileSize(upload.file.size);
self.refreshData(true);
} else {
upload.status = self.$root.uploadStatusEnum.ERROR;
upload.message = "Upload Error";
}
self.processUploads(uploads.slice(0, uploads.length - 1));
};
oReq.send(formData);
IE11 left, Chrome right.
I tried the following things to no avail:
Changing XMLHttpRequest to ActiveXObject
Disabling windows authentication in IIS

Get Date Header Asyncronously

As the title says, I want to get the Response Header Date value, but I keep getting the following warning :
Synchronous XMLHttpRequest on the main thread is deprecated because of
its detrimental effects to the end user's experience. For more help,
check https://xhr.spec.whatwg.org/.
My code :
function getxmlhttp () {
// although IE supports the XMLHttpRequest object, but it does not work on local files.
var forceActiveX = (window.ActiveXObject && location.protocol === "file:");
if (window.XMLHttpRequest && !forceActiveX) {
return new XMLHttpRequest();
}else {
try {
return new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {}
}
alert ("Your browser doesn't support XML handling!");
return null;
};
function srvTime(){
xmlHttp = getxmlhttp();
//xmlHttp.open('HEAD',window.location.href.toString(),false);
//need to send this to a non-volitile page
xmlHttp.open('GET',"blank.php",false);
xmlHttp.setRequestHeader("Content-Type", "text/html");
xmlHttp.send(null);
console.log("raw " + xmlHttp.getResponseHeader("Date"));
return xmlHttp.getResponseHeader("Date");
};
When I switch this line:
xmlHttp.open('GET',"blank.php",true);
To be true, the value returns NULL.
So can this be done, or do I have to just live with the warning in the console?
Thank you
As your title states, you must make the request asynchronously. That means you have to issue the request and wait for it to complete to get the information. Something like this should work:
function srvTime(callback) {
xmlHttp = getxmlhttp();
//xmlHttp.open('HEAD',window.location.href.toString(),false);
//need to send this to a non-volitile page
xmlHttp.onreadystatechange = function () {
if (xmlHttp.readyState == 4) { // The operation is complete
console.log("raw " + xmlHttp.getResponseHeader("Date"));
callback(xmlHttp.getResponseHeader("Date"));
xmlHttp = null;
}
};
xmlHttp.open('GET', "blank.php", true);
xmlHttp.setRequestHeader("Content-Type", "text/html");
xmlHttp.send(null);
};
Note that you must change the signature of your srvTime method. You can't return the data from it, the caller must supply a callback function that receives the date once the request completes.
An example of how you would use this function with the new signature is as follows:
srvTime(function (serverDate) {
document.getElementById("clock").innerHTML = "Game Time: " + serverDate;
});

CORS request firing without sending form data on window.onbeforeunload event in IE9

I've got a pretty simple function which is designed to grab the form data and send it via a CORS request. Basically it looks like this...
window.onbeforeunload = function() {
formData = getFormData();
logAbandonment(formData);
// return formData;
// alert(formData);
}
function logAbandonment(formData)
{
if(!cors_request) {
cors_request = true;
} else {
return;
}
var url = 'http://mydomain.lan/sub/index.php';
var xhr = createCORSRequest('POST', url);
if (!xhr) {
console.log('Error: CORS not supported.');
}
xhr.send(formData);
}
function createCORSRequest(method, url)
{
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// Check if the XMLHttpRequest object has a "withCredentials" property.
// "withCredentials" only exists on XMLHTTPRequest2 objects.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// Otherwise, check if XDomainRequest.
// XDomainRequest only exists in IE, and is IE's way of making CORS requests.
xhr = new XDomainRequest();
xhr.open(method, url);
xhr.onprogress = function () { };
xhr.ontimeout = function () { };
xhr.onerror = function () { };
xhr.onload = function() { };
} else {
// Otherwise, CORS is not supported by the browser.
xhr = null;
}
return xhr;
}
function getFormData()
{
if(typeof FormData == 'undefined') {
return serialize(document.getElementById('AppForm'));
} else {
return new FormData(document.getElementById('AppForm'));
}
}
Because this is IE9 I am working with, I am using the XDomainRequest javascript object.
It is successfully firing the ajax request, but here is where I am having a problem. It is firing it without sending the formData unless I uncomment either of the return or alert lines, in which case it works perfectly. When I do that, I can see the correct data it is supposed to be saying in the alert.
Another thing I noticed is this only happens when I either close the browser or close the tab. If I refresh the page, it works exactly like I want it to.
I thought maybe IE9 had some weird method of destroying the dom before the request was finished going out, but unfortunately, I can't figure out a way to set this to async false on XDomainRequest.
I've also tried setting a timeout, but that seems to break it completely.
Not an answer as much as a work-around, but I found this works perfectly when appending the query string onto the end of the url when calling xdr's open method.

JavaScript XMLHttpRequest.onreadystatechange

I'm attempting to do some AJAX and need to know why this code isn't firing a completed or error alert. I'm in Mozilla Firefox 20.0.1
PLEASE NOTE
This code IS updating the database (I have a select statement reading the exact record verifying it's updating) I'm just unsure as to why I can't get an alert when the response has completed.
I have these GLOBAL (at the top of the javascript page) declared variables.
var AjaxEnginePage;
var ClientInfoPage;
var XMLHTTP;
AjaxEnginePage = "AjaxEngine.aspx";
ClientInfoPage="getClientInfo.aspx";
Creating the connection.
//Creating and setting the instance of appropriate XMLHTTP Request object to a “XmlHttp” variable
function CreateXMLHTTP()
{
try
{
XMLHTTP = new ActiveXObject("Msxml2.XMLHTTP");
}
catch(e)
{
try
{
XMLHTTP = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(oc)
{
XMLHTTP = null;
}
}
//Creating object in Mozilla and Safari
if(!XMLHTTP && typeof XMLHttpRequest != "undefined")
{
XMLHTTP = new XMLHttpRequest();
}
}
Tying the connection:
function btnUpdateMe_OnClick() {
var me = encodeURIComponent(document.getElementById("MeTextBox").value);
// construct the URL
var requestUrl = AjaxEnginePage + "?Action=UpdateMe&Me=" + me;
CreateXMLHTTP();
// If browser supports XMLHTTPRequest object
if(XMLHTTP)
{
//Setting the event handler for the response
XMLHTTP.onreadystatechange = handleStateChange(me);
//Initializes the request object with GET (METHOD of posting),
//Request URL and sets the request as asynchronous.
XMLHTTP.open("get", requestUrl, true);
//Sends the request to server
XMLHTTP.send(null);
}
Handle State Change
function handleStateChange(me) {
switch (XMLHTTP.readyState) {
case 0: // UNINITIALIZED
case 1: // LOADING
case 2: // LOADED
case 3: // INTERACTIVE
break;
case 4: // COMPLETED
alert("Success");
break;
default: alert("error");
}
I can provide more code if needed. :( thanks.
Change:
XMLHTTP.onreadystatechange = handleStateChange(me);
to:
XMLHTTP.onreadystatechange = function() {handleStateChange(me);};
You're setting onreadystatechange to the result of calling the function, not to the function.

No response when using AJAX and JSON

function getIDs() {
alert("1");
var title = document.getElementById('title').value;
alert(title);
title = "http://www.imdbapi.com/?i=&t=" + title;
alert(title);
xmlhttp=new XMLHttpRequest();
alert("2");
xmlhttp.open("GET",title,true);
alert("3");
xmlhttp.send();
alert("4");
var imdbData = xmlhttp.responseText;
alert(imdbData);
var imdbJSON = JSON.parse(imdbData);
//document.getElementById('title').value = imdbJSON.Title;
alert(imdbJSON.Title);
document.getElementById('imdbid').value = imdbJSON.ID;
return true;
}
I'm trying to fetch the ID of a film based upon it's title, the function gets called successfully and the alerts are correct until the alert which returns "imdbData", which returns a blank alert, then no more alerts occur, I'm unsure where I'm going wrong here. Any assistance would be appreciated.
You're opening it asynchronously. To make it synchronous, change this:
xmlhttp.open("GET",title,true);
To this:
xmlhttp.open("GET",title,false);
A usually-considered-better way would be to make it work with asynchronicity:
function getIDs() {
alert("1");
var title = document.getElementById('title').value;
title = "http://www.imdbapi.com/?i=&t=" + title;
xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange=function() {
if(xmlhttp.readyState==4) {
var imdbData = xmlhttp.responseText;
var imdbJSON = JSON.parse(imdbData);
document.getElementById('title').value = imdbJSON.Title;
document.getElementById('imdbid').value = imdbJSON.ID;
}
};
xmlhttp.open("GET",title,true);
xmlhttp.send();
return true;
}
Additionally, you cannot request pages from other domains. You may need to switch to JSONP if the API you're using supports it, or use your web server as a proxy.
You are not allowed to do cross site scripting with JavaScript which is why you get nothing in return.
You need to be on the same domain as you post your AJAX call to.
Use a serverside script to parse the URL for you instead.

Categories