Vilican
Vilican

Reputation: 157

Removing an unwanted part of an external JavaScript

I actually load an external JavaScript on my page this way:

<script type='text/javascript' src='http://somedomain.com/somescript.php'></script>

Note: it is a PHP file, but it produces and gives back a JavaScript code

However, there are two parts of the script - this is the first one, which I need:

document.getElementById('latest').innerHTML= "the lastest version of product";

And here is the second, which is unwanted, and I need to get rid of it:

var img = document.createElement("img");
img.src = "http://somedomain.com/tracking.php";
document.getElementsByTagName("body")[0].appendChild(img);

How can I get rid of this one image, which tracks users, before it will send the data, but leave the showing of the lastest version intact without changes.

Upvotes: 2

Views: 311

Answers (5)

Amit
Amit

Reputation: 46323

Similar to what others suggested - cause the unwanted script part to fail, but using a cleaner "block", we can snatch the img identifier and prevent it from being used. We do that be using Object.defineProperty(), which, by default creates a non-configurable, non-writable property.

Object.defineProperty(window, 'img', {value: null}); // this snatches the identifier

img = document.createElement('img'); // <- this won't work

alert(img); // <- this is null

Upvotes: 2

Ingmars
Ingmars

Reputation: 998

Have you tried CSS?

<head>
<style>
    img[href *= "somedomain.com/tracking.php"] {
        display: none !important;
    }
</style>
</head>
<body>
    <script src="yourscript"></script>
</body>

Key factor here is that browsers will ignore images, which are hidden. Thus you need to move the external script to the body.

Analytics providers tend to put themselves on top of everything (head), but there is no real reason for that 99.9% of the time. They just feel very important.

Upvotes: 0

James Brierley
James Brierley

Reputation: 4670

Similar to Michael's solution, it should be possible to prevent the javascript from executing by running some code first. If you run the following before adding the script:

document.getElementsByTagName("body")[0].appendChild = function() {};

Their script will be unable to add the image to the dom. If you need to use that method for yourself, assign it to a different variable first. Or try:

var oldMethod = document.getElementsByTagName("body")[0].appendChild;
document.getElementsByTagName("body")[0].appendChild = function(node) {
    if (node.src !== "http://somedomain.com/tracking.php") {
        oldMethod(node);
    }
}

Upvotes: 2

Stephen Thomas
Stephen Thomas

Reputation: 14053

I alluded to this in my comments, but I think the only way to achieve what you ask is to AJAX load the script (if the server permits it) and parse out the offending code. That seems overly complex and error-prone, and borderline unethical. I would suggest that you contact the host of the script somedomain.com and ask if they can provide a version without the image tracker. If they decline, then you should respect their wishes. After all, it is their content (the first part of the script) that you want, and they have every right to specify your obligations to use it. If you don't like their terms, don't use their content.

(BTW, I'm not suggesting that image trackers are a good thing. I despise them.)

Upvotes: 0

baao
baao

Reputation: 73241

I'm not sure if it would work and it's a hack, but you could try it with a try catch and const. const might work on firefox and chrome, you'd need a polyfill for safari and older browsers.

<script>
const img = '';
try {
    var script = document.createElement('script');
    script.src = 'http://somedomain.com/somescript.php';
    document.body.appendChild(script);
} catch (err) {}
</script>

By defining the global const it should throw an error when the variable is assigned, then we handle the error by doing nothing with it, so the part before the error was thrown should still be loaded without interrupting the rest of the script.

Upvotes: 1

Related Questions