Sockie
Sockie

Reputation: 189

Using GM xmlhttpRequest instead of an iframe to display pertinent info from an external page

I have loaded an https page on Amazon.co.uk and I wish to display use 'GM xmlhttpRequest' to request the price of an item on a linked page.

What I’ve been doing so far

I tried to use an iFrame to display the window:

var prodLinks = $("td.product_description a:contains('View Amazon Product Page')");
if (prodLinks.length) {
var iframeSrc = prodLinks[0].href;
iframeSrc = iframeSrc.replace (/http:\/\//, "https://")
    $("body").append ('<iframe id="gmIframe" src="' + iframeSrc + '"></iframe>');


$("#gmIframe").css ( {
    "position":     "absolute",
    "bottom":       "1em",
    "left":         "2em",
    "height":       "25%",
    "width":        "84%",
    "z-index":      "17",
    "background":   "#00FF00"
} );
}

The problem with this approach is, that whilst it works, the contents of the iFrame is too cluttered, so I cannot see what I need to, at a glance.

The stuff I want to see

Let us suppose that the linked page is https://www.amazon.co.uk/gp/product/B001AM72BM/

The relevant HTML snippet from the aforementioned page:

<tr id="actualPriceRow">
<td id="actualPriceLabel" class="priceBlockLabelPrice">Price:</td>
<td id="actualPriceContent"><span id="actualPriceValue"><b class="priceLarge">£2.85</b></span>
<span id="actualPriceExtraMessaging">

How, exactly, can I use GM xmlhttpRequest to get the page

Background : I’m using something similar to GreaseMonkey

This is for Greasekit on Fluid.app (which is very old, but I must using it). You probably don’t even need to know that as it’s very similar to Greasekit. So, for the purposes of this question, you can just pretend it is.

My attempt at answer

I would try:

GM_xmlhttpRequest({
method: "GET",
url: "https://www.amazon.co.uk/gp/product/B001AM72BM/",
onload : function(response) {
// do something with the result here
document.getElementByClass(‘priceLarge').innerHTML = response.responseText;
}
});

Upvotes: 3

Views: 930

Answers (1)

Brock Adams
Brock Adams

Reputation: 93473

Use jQuery to parse the response from GM_xmlhttpRequest, and unlike for an iframe, you don't need to rewrite the URL to SSL.

So:

  1. Rather than add an iframe, add a node that will contain your price.
  2. Grab the product URL as before.
  3. Fetch the URL with GM_xmlhttpRequest.
  4. Use jQuery to find the .priceLarge node.
  5. Write the contents of that node to the node created in step 1.

The complete code, with some UI and error handling, looks like this. I tested it on your sample page and it works.

var prodLinks = $("td.product_description a:contains('View Amazon Product Page')");
if (prodLinks.length) {
    //--- Make a place to put the price.
    $("td.buybox table td.v_prod_box_topleft").append (
        '<p id="gmPriceResult">Fetching...</p>'
    );

    GM_xmlhttpRequest ( {
        method:     'GET',
        url:        prodLinks[0].href,
        onload:     getItemPrice,
        onabort:    reportAJAX_Error,
        onerror:    reportAJAX_Error,
        ontimeout:  reportAJAX_Error
    } );
}

function getItemPrice (resp) {
    /*--- Strip <script> tags and unwanted images from response
        BEFORE parsing with jQuery.  Otherwise the scripts will run and the
        images will load -- wasting time and bandwidth and increasing risk
        of complications.
    */
    var respText    = resp.responseText.replace (/<script(?:.|\n|\r)+?<\/script>/gi, "");
    respText        = respText.replace (/<img[^>]+>/gi, "");
    var respDoc     = $(respText);

    //-- Now fetch the price node:
    var priceNode   = respDoc.find (".priceLarge:first");
    if (priceNode.length) {
        $("#gmPriceResult").text (priceNode.text () );
    }
    else {
        $("#gmPriceResult").text ("Price not found!");
    }
}

function reportAJAX_Error (resp) {
    alert ('Error ' + resp.status + '!  "' + resp.statusText + '"');
}

Upvotes: 1

Related Questions