I am trying to catch every XHR Request send from Gmail and add a classification lable in the body of the mail. I am not sending new XHR requests. My code is working like filter for all XHR requests by overriding XMLHttpRequest's open/send function. I am working on this issue from last week.Please help me.
function sendEmail() {
//alert("In sendEmail()");
var overrideMethods = function() {
//alert("In overrideMethods()");
window.XMLHttpRequest.prototype._open = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function (method, url, async, user, password) {
this.openParams = {
url: url
};
return window.XMLHttpRequest.prototype._open.apply(this, arguments);
};
window.XMLHttpRequest.prototype._send = XMLHttpRequest.prototype.send;
window.XMLHttpRequest.prototype.send = function send() {
var defered = false;
var searchPattern = /(&selectedLable=|^selectedLable=)(.*?)&/;
alert("In send()");
if (typeof arguments[0] === "string" && arguments.length === 1) {
var str = arguments[0];
//alert("Inside of first if");
//alert("str : " + str);
if (this.openParams.url.match(/&act\=sm/) && str.match(/&bcc\=/) && str.match(searchPattern)) {
defered = true;
var sendData = (str.match(searchPattern) && str.match(searchPattern)[2]);
var tag = JSON.parse(decodeURIComponent(sendData)).tag;
alert("tag : " + tag);
/* Modify the POST url to reflect the tag */
str = str.replace(searchPattern, "");
str = str.replace(/&subject=/, "&subject=" + tag + ": ");
str = str.replace(/&body\=/, "&body=<br>" + tag.toLowerCase() + "<br>");
/* Capitalize the tag. */
arguments[0] = str + "&acn=!" + tag.charAt(0).toUpperCase() + tag.slice(1).toLowerCase();
window.XMLHttpRequest.prototype._send.apply(this, arguments);
}
}
if (!defered) {
window.XMLHttpRequest.prototype._send.apply(this, arguments);
}
};
}
window.location.href = 'javascript: (' + overrideMethods.toString().replace(/(\n|\ {2,})/gm, '') + ')();';
}
sendEmail();
I found this link on stack overflow :
Overriding XMLHttpRequest's send method
Please note my method is working fine for native chrome extension, but its not working for crossrider extension.
Related
I've seen lots of variations on this question, but none of them applies to this specific situation. I'm a bit confused because of all the data and object types.
Consider the following code in JavaScript:
function postRequest(url, params, success, error, keepactive = 1)
{
let req = false;
try
{
// most browsers
req = new XMLHttpRequest();
} catch (e)
{
// IE
try
{
req = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e)
{
// try an older version
try
{
req = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e)
{
return false;
}
}
}
if (keepactive === 0)
{
ajaxcalls.push(req);
console.log(ajaxcalls.length + ' calls active');
} else if (keepactive === 2)
{
console.log('Filter call: ' + ajaxcalls.length + ' calls active');
filtercall = req;
} else if (keepactive === 3)
{
console.log('Jump call: ' + ajaxcalls.length + ' calls active');
jumpcall = req;
}
if (!req) return false;
if (typeof success != 'function') success = function ()
{
};
if (typeof error != 'function') error = function ()
{
};
req.onreadystatechange = function ()
{
if (req.readyState === 4)
{
// Success! Remove req from active calls.
if (keepactive === 0)
{
for (let i = ajaxcalls.length - 1; i >= 0; i--)
{
if (ajaxcalls[i] === req)
{
ajaxcalls.splice(i, 1);
console.log(ajaxcalls.length + ' calls active');
}
}
}
return req.status === 200 ?
success(req.responseText) : error(req.status);
// dus eigenlijk displayUpdateWorksheet(req.responseText)
// dus eigenlijk displayUpdateWorksheetError(req.status)
}
}
req.open("POST", url, true);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.send(params);
return req;
}
function uploadPicture(myindex, stringid)
{
let file = document.getElementById("file").files[0];
let contents = new FileReader(); // no arguments
contents.readAsDataURL(file);
contents.onload = function ()
{
// console.log(contents.result);
let filename;
let client;
let field = myindex;
let filecontainer = document.getElementById('file' + myindex);
if (filecontainer != null)
{
filename = filecontainer.innerHTML.replace(/\+/g, '+').replace(/&/g, '&').replace(/#/g, '#').replace(/%/g, '%');
}
let clientcontainer = document.getElementById('myclient');
if (clientcontainer != null)
{
client = clientcontainer.innerHTML.replace(/\+/g, '+').replace(/&/g, '&').replace(/#/g, '#').replace(/%/g, '%');
}
alert('Picture uploaded!');
// let post_array = { client: client, stringid: stringid, filename: filename, field: field, contents: contents.result }
postRequest(
'ajaxcalls/ajaxUploadPicture.php', // url
'&client=' + client +
'&stringid=' + stringid +
'&filename=' + filename +
'&field=' + myindex +
'&contents=' + contents.result +
'&type=' + file.type,
function (responseText)
{
return drawOutputUploadPicture(myindex, responseText);
}, // success
drawErrorUploadPicture // error
);
}
contents.onerror = function ()
{
console.log(contents.error);
};
};
And the following PHP:
$data = $_POST['contents'];
$contents = preg_replace('#data:image/[^;]+;base64,#', '', $data);
$contents = base64_decode($contents);
...
file_put_contents($file_full, $contents);
($file_full is correct here: the file is saved at the right spot. I've just cut some irrelevant code there: nothing in $contents is changed after this.)
When I upload a 52K image, I lose about 1K and the resulting image cannot be opened. What's going on?
The main issue is that 1) I'm using POST with 2) multiple variables and 3) Vanilla JavaScript. I've seen no working examples of that.
When I open the original and copy as text, the beginning is the same:
Original: ���� JFIF ` ` ���Exif
Copy: ���� JFIF ` ` ���Exif
Then a series of NUL's in both files. Then the files start deviating:
Original:
2021:07:22 16:21:52 2021:07:22 16:21:52 L o e k v a n K o o t e n ��"http://ns.adobe.com/xap/1.0/ <?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?>
<x:xmpmeta xmlns:x="adobe:ns:meta/"><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><rdf:Description rdf:about="uuid:faf5bdd5-ba3d-11da-ad31-d33d75182f1b" xmlns:dc="http://purl.org/dc/elements/1.1/"/><rdf:Description rdf:about="uuid:faf5bdd5-ba3d-11da-ad31-d33d75182f1b" xmlns:xmp="http://ns.adobe.com/xap/1.0/"><xmp:CreateDate>2021-07-22T16:21:52.056</xmp:CreateDate></rdf:Description><rdf:Description rdf:about="uuid:faf5bdd5-ba3d-11da-ad31-d33d75182f1b" xmlns:dc="http://purl.org/dc/elements/1.1/"><dc:creator><rdf:Seq xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><rdf:li>Loek van Kooten</rdf:li></rdf:Seq>
</dc:creator></rdf:Description></rdf:RDF></x:xmpmeta>
Copy:
2021:07:22 16:21:52 2021:07:22 16:21:52 L o e k v a n K o o t
e n
�BȚ��ۜ˘YؙK���K�\�K���X��]�Y�[�I�����YI��SL\�ZR��Tޓ�ޚ��Y �σB��\Y]H[�ΞH�YؙN��ΛY]Kȏ������[�Μ��H������˝�˛ܙ��NNNK��̌�\��\�[�^[��ȃ�&Fc�FW67&�F���&Fc�&�WC�'WV�C�fcV&FCR�&6B�F�C3�C36CsS�&c""����3�F3�&�GG���W&���&r�F2�V�V�V�G2���"���&Fc�FW67&�F���&Fc�&�WC�'WV�C�fcV&FCR�&6B�F�C3�C36CsS�&c""����3����&�GG����2�F�&R�6�������
���� ɕ�ѕ�є����Ĵ�ܴ��P�������ȸ�������
ɕ�ѕ�є��ɑ���͍ɥ�ѥ����ɑ���͍ɥ�ѥ���ɑ�酉�����ե�际�Չ��Ե��͐��ő�����ĵ��͐����ɘň��ᵱ��鑌����輽��ɰ��ɜ�����������̼ĸļ�<dc:creator����\H[�Μ��H������˝�˛ܙ��NNNK��̌�\��\�[�^[��ȏ����O��Z��[����[�ܙ��O�ܙ���\O�B�BBO�ΘܙX]�ܙ��\�ܚ[ۏ�ܙ�����������WF4
Anyone recognizes what's going on here?
For some reason, in this case $_POST['contents'] contains spaces. If I replace these with + the image comes out nicely. I imagine that when a file is sent as a $_POST variable, it gets split with a space every so many characters.
I am trying to add the parameter "referer=" to my url corresponding to the trafic referer of a new session.
I used some of the code from this topic... but it keeps reloading the page in a loop... then the url is like :
https://example.com?refere=facebookreferer=facebookreferer=facebook
Note:
I have been using this solution 1 :
function addOrUpdateUrlParam(name, value)
{
var ref = document.referrer;
var refsplit = ref.split(".")[1];
var href = window.location.href;
var regex = new RegExp("[&\\?]" + name + "=");
if(regex.test(href))
{
regex = new RegExp("([&\\?])" + name + "=\\d+");
{
else
{
if(href.indexOf("?") > -1)
window.location.href = href + "&" + name + "=" + value;
else
window.location.href = href + "?" + name + "=" + value;
}
if (refsplit != "example") {
return addOrUpdateUrlParam("referer", refsplit);
}
}
And this solution 2:
function () {
var ref = document.referrer;
var refsplit = ref.split(".")[1];
if (refsplit != "example") {
return location.search += "referer=" + refsplit;
}
}
Edit 1:
Thanks to Prasanth I improved the code to :
function () {
var ref = document.referrer;
var refsplit = ref.split(".")[1];
var currentUrl = location.href;
var url1 = currentUrl += "?referer="+refsplit;
var url2 = currentUrl += "&referer="+refsplit;
if(currentUrl.indexOf("?") < 0) {
return window.location = url1;
} else {
return window.location = url2;
}
}
However, it is returning both conditions :
https://example.com/?referer=facebook&referer=facebook
Edit 2:
So after many attempts, I achieved it by working with the parameters of the url (location.search) instead of the full url (location.href) :
function addRefererParam () {
var ref = document.referrer; //Get Referrer
var refDomain = ref.match(/[^(?:http:\/\/|www\.|https:\/\/)]([^\/]+)/i)[0]; //Extract Referrer Domain name for better readability
var params = location.search; //Get Url parameters
if (refDomain.match(/mydomain|null|undefined/i)) { //check if domain not null or own domain.
return params ;
} else {
return params += "utm_source=" + refDomain; //create new query string with referrer domain
}
}
However, it is no making a persistent query string through browsing... how can I make the new parameters persistent ?
Obtain the url of the current window and after the domain name just concat your url with &referer=value.
var currentUrl = location.href;
var paramsInUrl = currentUrl.split('&');
var flag = true;
for(var i in paramsInUrl)
{
if(!paramsInUrl[i].includes('referer=')
{
continue;
}
else
{
flag = false;
break;
}
}
if(flag)
{
currentUrl += '&referer='+value;
window.location = currentUrl;
}
For what it's worth (because the more generic question of just how to do this generally is what lead me to this post), I've made a 178 byte helper function that takes in an object of the query parameters you want to add to a url for a GET request (in similar format for how you might add headers to a request) and made an npm package for it here: https://www.npmjs.com/package/add-query-params-to-url
Hopefully this is helpful to some.
My goal was to generate a PDF from every page included in the sitemap of a website created with Rails. I'm using PhantomJS to get it. I'm quite new in this field, but I could do it, but when I was finished, I realized that it would be usable also to see at the beginning of every PDF the url of the page from which the PDF was generated, so I can browse quicker to the page (the site has over hundred pages).
Here is the Javascript:
// Render Sitemap to file
var RenderUrlsToFile, arrayOfUrls, system;
system = require("system");
/*
Render given urls
#param array of URLs to render
#param callbackPerUrl Function called after finishing each URL, including the last URL
#param callbackFinal Function called after finishing everything
*/
var getFileNumber = function(urlIndex) {
if (urlIndex <10) {
return "00" + urlIndex;
} else {
if (urlIndex <100) {
return "0" + urlIndex;
} else {
return urlIndex;
}
}
};
RenderUrlsToFile = function(urls, callbackPerUrl, callbackFinal) {
var getFilename, next, page, retrieve, urlIndex, webpage;
urlIndex = 0;
webpage = require("webpage");
page = null;
getFilename = function() {
return "rendermulti-" + getFileNumber(urlIndex) + ".pdf";
};
next = function(status, url, file) {
page.close();
callbackPerUrl(status, url, file);
return retrieve();
};
retrieve = function() {
var url;
if (urls.length > 0) {
url = urls.shift();
urlIndex++;
page = webpage.create();
page.viewportSize = {
width: 1920,
height: 1880
};
page.settings.userAgent = "Phantom.js bot";
return page.open(url, function(status) {
var file;
file = getFilename();
if (status === "success") {
return window.setTimeout((function() {
// !!!!!!!!!!!!! Doesn't work !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
page.evaluate(function() {
var x = document.getElementById("logoAndNavigation");
var newP = document.createElement("P")
var textnode = window.location.protocol + "//" + window.location.host + "/" + window.location.pathname;
newP.appendChild(textnode)
x.insertBefore(newP, x.childNodes[0]);
});
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
page.render("tempPdfs/" + file);
return next(status, url, file);
}), 200);
} else {
return next(status, url, file);
}
});
} else {
return callbackFinal();
}
};
return retrieve();
};
// This makes an array with all the urls inside the sitemap
var arrayOfUrls = [''];
var page = require('webpage').create();
page.open('http://localhost:3000/sitemap.xml', function() {
var content = page.content;
parser = new DOMParser();
xmlDoc = parser.parseFromString(content,'text/xml');
var loc = xmlDoc.getElementsByTagName('loc');
for(var i=0; i < loc.length; i++)
{
var url=loc[i].textContent;
arrayOfUrls.push(url);
}
});
RenderUrlsToFile(arrayOfUrls, (function(status, url, file) {
if (status !== "success") {
return console.log("Unable to render '" + url + "'");
} else {
return console.log("Rendered '" + url + "' at '" + file + "'");
}
}), function() {
return phantom.exit();
});
I tried to solve the issue with the urls, with the code framed with the comment
// !!!!!!!!!!!!! Doesn't work !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
I wanted to show the url inside an element of the page, that has the id #logoAndNavigation, but I get this error:
NOT_FOUND_ERR: DOM Exception 8: An attempt was made to reference a Node in a context where it does not exist.
If I use only a string like "hello" inside the variable textnode, it works, but not if I try to use the url of the page.
Can anyone please help me?
Thank you in advance!
appendChild expects a node not a string. You probably mean to use
var x = document.getElementById("logoAndNavigation");
var newP = document.createElement("p"); // small p
var textnode = window.location.protocol + "//" + window.location.host + "/" + window.location.pathname;
newP.innerHTML = textnode; // this
x.insertBefore(newP, x.childNodes[0]);
You can also use the example of printheaderfooter.js to add the URL directly to the header or footer.
can anyone tell me why this is not working?
ui = (function() {
collabElement = document.getElementById( 'approveCollab' );
if(collabElement)
collabElement.onclick = function(){editor.collaborate(); removeOverlay();}
deleteElement = document.getElementById( 'approveDelete' );
if(deleteElement)
deleteElement.onclick = function(){editor.deletePost(); removeOverlay();}
})();
"collaborate" is an exported function in "editor.js" file.
removeOverlay()" is a function in the same file.
when "collabElement" is clicked only "removeOverlay" is being called.
there are no errors, just that the function is not called at all.
these are the function being called from editor.js:
function collaborate( event ) {
console.log("started");
var url = '';
var postID = document.querySelector('.save').getAttribute('id');
var recipient = document.querySelector('.collab-input').value;
//validate email syntax
var atpos=recipient.indexOf("#");
var dotpos=recipient.lastIndexOf(".");
if (atpos<1 || dotpos<atpos+2 || dotpos+2>=x.length){
console.log("wrong email");
document.querySelector('.email-error').style.display = "block";
}
else{
console.log("sending email to " + recipient);
document.querySelector('.email-error').style.display = "none";
if(postID != "new"){
url = url + "?id=" + postID + "&recipient=" + recipient;
var request = new XMLHttpRequest();
request.open("GET", "collaborate"+url, true);
request.send();
}
}
}
function deletePost( event ) {
var url = '';
var postID = document.querySelector('.save').getAttribute('id');
if(postID != "new"){
url = url + "?id=" + postID;
var request = new XMLHttpRequest();
request.open("GET", "delete"+url, true);
request.send();
}
}
If you want to call a function add () to it.
editor.collaborate()
(instead of editor.collaborate, which will just only address the function)
I suspect the problem is that your IIFE is not returning anything; ui will always be undefined. I think you want this:
ui = (function() {
collabElement = document.getElementById( 'approveCollab' );
if(collabElement)
collabElement.onclick = function(){editor.collaborate; removeOverlay();}
//return collabElement so it's assigned to ui
return collabElement;
})();
EDIT
While it's true your IIFE does not return anything, it looks like Peter's answer is more relevent to you at the moment; collaborate is not being called. His appears to be the right answer to this question.
I consume a WebService .NET using Javascript with this code:
// This is where you can place your Javascript code
// var xmlHTTP;
function MButton1Click(event) {
testarTexto();
}
function WebSvc() // Class Signature
{
WebSvc.prototype.CallWebService = function(url, soapXml, callback)
{
var xmlDoc = null;
if (window.XMLHttpRequest)
{
xmlDoc = new XMLHttpRequest(); //Newer browsers
}
else if (window.ActiveXObject) //IE 5, 6
{
xmlDoc = new ActiveXObject("Microsoft.XMLHTTP");
}
if (xmlDoc)
{
var self = this;
xmlDoc.onreadystatechange = function() { self.StateChange(xmlDoc, callback); };
xmlDoc.open("POST", url, true);
xmlDoc.setRequestHeader("Content-Type", "text/xml");
xmlDoc.setRequestHeader("Content-Length", soapXml.length);
xmlDoc.send(soapXml);
}
else
{
if (callback)
{
callback(false, "unable to create XMLHttpRequest object");
}
}
};
WebSvc.prototype.StateChange = function(xmlDoc, callback)
{
if (xmlDoc.readyState === 4)
{
var text = "";
if (xmlDoc.status === 200)
{
text = xmlDoc.responseText;
}
// Perform callback with data if callback function signature was provided,
if (callback !== null)
{
callback(xmlDoc.status === 200, text);
}
}
};
}
function createSoapHeader(message)
{
var soap = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
soap = soap + "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">";
soap = soap + " <soap:Body>";
soap = soap + " <TesteDeTexto xmlns=\"http://tempuri.org/\">";
soap = soap + " <pTexto>" + message + "</pTexto>";
soap = soap + " </TesteDeTexto>";
soap = soap + " </soap:Body>";
soap = soap + "</soap:Envelope>";
return soap;
}
function callComplete(result, data)
{
if (result)
{
//alert(getTagValue(data, "TesteDeTextoResult"));
document.getElementById('MTextArea1').value = getTagValue(data, "TesteDeTextoResult");
}
else
{
alert("Error occurred calling web service.\n" + result + "\n" +data);
}
}
function testarTexto()
{
var soap = createSoapHeader("TESTE");
//document.getElementById('texto').value = soap;
// alert(soap);
var webServiceCall = new WebSvc();
webServiceCall.CallWebService("http://localhost/WebService/Test.asmx", soap, callComplete);
}
function getTagValue(inputStr, tagName)
{
var stag = "<" + tagName + ">";
var etag = "<" + "/" + tagName + ">";
var startPos = inputStr.indexOf(stag, 0);
if (startPos >= 0)
{
var endPos = inputStr.indexOf(etag, startPos);
if (endPos > startPos)
{
startPos = startPos + stag.length;
return inputStr.substring(startPos, endPos);
}
}
return "";
}
But it only works with methods that return a string as result. How can I make when I need to return a dataSet?
Just use jQuery ^^ There you find a lot of different handlers for different return types. A dataSet could be encoded in JSON or XML, what is transfered automatically into JS data structures by jQuery. Additionally, the JS code looks much cleaner, because jQuery comes with a bunch of AJAX methods. To transform the xml response into JS data structures, just set the dataType to xml in your jQuery request. For instance:
jQuery.ajax('url/to/your/WS', {
dataType: "xml",
data: {
postParam1 : "foo"
},
success: function(data) {
alert(data.find("MyNode"));
}
});
How to work with the parsed xml response in JS can be found here.