🏠 back to Observable

tips for embedding views of other websites?

#1

I have been trying out different techniques for embedding an external webpage, but with limited success.

Any tips for embedding external sites? Preferably with ‘vanila’ JS or D3.js?

This is the page I’m using to test: https://www.eib.org/en/about/accountability/complaints/cases/index.htm
… which appears to be a React.js application, though I am looking for a general approach that can be used to embed any external site.

The <iframe src=""> approach turns up a blank box, as does the <object> approach.

A JQuery-based approach works, but the site spills over the following cells, even when I define a cell height, like this:

$("#jQueryEmbed").load("https://www.eib.org/en/about/accountability/complaints/cases/index.htm");
html`<div id="jQueryEmbed" style="height:500px"></div>`

I’d be grateful for pointers on what I might be able to do to put up a view of page that will fit ‘within’ a cell / container. A jQuery approach would be OK, but I’d be especially happy for pointers on doing this with ‘pure’ JS or D3.js, as I am still very new and trying to stick to using these two tools.

Thanks in advance for your time and insights!

#2

The iframe and object approaches are failing because of security reasons. Firefox, at least, displays this message in those cells:

Blocked by Content Security Policy
An error occurred during a connection to www.eib.org.
Firefox prevented this page from loading in this way because the page has a content security policy that disallows it.

As a side comment, you may want to make sure you really need to embed an external page like this instead of just linking to it since any approach is going to be fraught with issues.

JQuery’s .load fetches the HTML file from the site as text and then displays that as HTML. This will fail to run scripts due to the aforementioned security reasons but it can at least show the HTML. You can do much the same with ordinary JS and this snippet (adapted from Embedded notebook) does the same thing without the spillover:

Object.assign(html`<iframe style="width:100%;height:500px;border:none;">`, 
  {srcdoc: await fetch('https://www.eib.org/en/about/accountability/complaints/cases/index.htm')
    .then(d => d.text())})
1 Like
#3

Thanks Bryan!

I suppose that I don’t really need to embed websites :wink: I am preparing some notebooks that will compare how independent accountability mechanisms are disclosing their case-handing information. Since I’m grabbing the names of various data attributes, I thought it’d be fun (and that it would visually make more sense) if I could display the source page next to the attributes I’m grabbing.

Here’s an example without the embed, where I use a small table to show the Asian Development Bank’s presentation of case details:

Just not as illustrative or fun :neutral_face:

I didn’t initially see the error message about resources being blocked for security reasons. Mike’s already informed me to use the browser’s inspect tool. Sorry for not being better at it yet (I’ll try to do better in the future). I see now that Chrome reports this: Access to XMLHttpRequest at ... has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

… By the way, since this isn’t an official work product, and since I’m compiling public information, I finally get to make use of your Google Spreadsheets as database back-end trick. Thanks so much! I still have a lot to learn, like how to avoid issues where Google Spreadsheet cells have breaks… but I’m really happy with how it’s taking shape.

Also, thanks to you and everyone for all the help over the last year. I am really excited to be starting to use JS to help me explore the world.

1 Like
#4

Maybe a screenshot would work?

I really appreciate the kind words, Aaron! Sounds like you’re working on some cool projects and I’m looking forward to see how they turn out.

1 Like
#5

Ahh… a good old-fashioned screenshot. :slight_smile: Looks like this will have to work in the end, as trying your code for the ADB complaints registry fails to fetch with another CORS error.

I’ve had a lot of fun reading about the many Observable ‘ouroboroi’ (as Jeremy playfully described his famous example), so I thought it’d be fun to try out a similar approach. Plus it takes longer to screenshot and host than it does just to copy and past your code :wink:

I’ll happily share when I get further with these comparisons – hopefully I can write out something that is at least a bit interesting and visually dynamic. Thanks for your encouragement!