Skip to content

Commit

Permalink
docs(learn): Add hint that copying the iframe example will lead to er…
Browse files Browse the repository at this point in the history
…rors (mdn#23413)

* docs(learn): Add hint that copying the iframe example will lead to errors

* docs(learn): Add hint that copying the iframe example will lead to errors
  • Loading branch information
bsmth committed Jan 5, 2023
1 parent cbb08c7 commit 2b9c5bb
Showing 1 changed file with 36 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -123,49 +123,50 @@ body {
```

```js hidden
const textarea = document.getElementById('code');
const reset = document.getElementById('reset');
const solution = document.getElementById('solution');
const output = document.querySelector('.output');
const textarea = document.getElementById("code");
const reset = document.getElementById("reset");
const solution = document.getElementById("solution");
const output = document.querySelector(".output");
let code = textarea.value;
let userEntry = textarea.value;

function updateCode() {
output.innerHTML = textarea.value;
}

reset.addEventListener('click', function() {
reset.addEventListener("click", function () {
textarea.value = code;
userEntry = textarea.value;
solutionEntry = htmlSolution;
solution.value = 'Show solution';
solution.value = "Show solution";
updateCode();
});

solution.addEventListener('click', function() {
if (solution.value === 'Show solution') {
solution.addEventListener("click", function () {
if (solution.value === "Show solution") {
textarea.value = solutionEntry;
solution.value = 'Hide solution';
solution.value = "Hide solution";
} else {
textarea.value = userEntry;
solution.value = 'Show solution';
solution.value = "Show solution";
}
updateCode();
});

const htmlSolution = '<iframe width="420" height="315" src="https://www.youtube.com/embed/QH2-TGUlwu4" frameborder="0" allowfullscreen>\n</iframe>\n\n<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d37995.65748333395!2d-2.273568166412784!3d53.473310471916975!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x487bae6c05743d3d%3A0xf82fddd1e49fc0a1!2sThe+Lowry!5e0!3m2!1sen!2suk!4v1518171785211" width="600" height="450" frameborder="0" style="border:0" allowfullscreen>\n</iframe>';
const htmlSolution =
'<iframe width="420" height="315" src="https://www.youtube.com/embed/QH2-TGUlwu4" frameborder="0" allowfullscreen>\n</iframe>\n\n<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d37995.65748333395!2d-2.273568166412784!3d53.473310471916975!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x487bae6c05743d3d%3A0xf82fddd1e49fc0a1!2sThe+Lowry!5e0!3m2!1sen!2suk!4v1518171785211" width="600" height="450" frameborder="0" style="border:0" allowfullscreen>\n</iframe>';
let solutionEntry = htmlSolution;

textarea.addEventListener('input', updateCode);
window.addEventListener('load', updateCode);
textarea.addEventListener("input", updateCode);
window.addEventListener("load", updateCode);

// stop tab key tabbing out of textarea and
// make it write a tab at the caret position instead

textarea.onkeydown = function(e){
textarea.onkeydown = function (e) {
if (e.keyCode === 9) {
e.preventDefault();
insertAtCaret('\t');
insertAtCaret("\t");
}

if (e.keyCode === 27) {
Expand All @@ -178,7 +179,10 @@ function insertAtCaret(text) {
let caretPos = textarea.selectionStart;

const front = textarea.value.substring(0, caretPos);
const back = textarea.value.substring(textarea.selectionEnd, textarea.value.length);
const back = textarea.value.substring(
textarea.selectionEnd,
textarea.value.length
);
textarea.value = front + text + back;
caretPos += text.length;
textarea.selectionStart = caretPos;
Expand All @@ -189,10 +193,10 @@ function insertAtCaret(text) {

// Update the saved userCode every time the user updates the text area code

textarea.onkeyup = function(){
textarea.onkeyup = function () {
// We only want to save the state when the user code is being shown,
// not the solution, so that solution is not saved over the user code
if (solution.value === 'Show solution') {
if (solution.value === "Show solution") {
userEntry = textarea.value;
} else {
solutionEntry = textarea.value;
Expand All @@ -206,9 +210,11 @@ textarea.onkeyup = function(){

## iframes in detail

So, that was easy and fun, right? {{htmlelement("iframe")}} elements are designed to allow you to embed other web documents into the current document. This is great for incorporating third-party content into your website that you might not have direct control over and don't want to have to implement your own version of — such as video from online video providers, commenting systems like [Disqus](https://disqus.com/), maps from online map providers, advertising banners, etc. The live editable examples you've been using through this course are implemented using `<iframe>`s.
So, that was easy and fun, right? {{htmlelement("iframe")}} elements are designed to allow you to embed other web documents into the current document. This is great for incorporating third-party content into your website that you might not have direct control over and don't want to have to implement your own version of — such as video from online video providers, commenting systems like [Disqus](https://disqus.com/), maps from online map providers, advertising banners, etc. Even the live editable examples you've been using through this course are implemented using `<iframe>`s.

There are some serious [Security concerns](#security_concerns) to consider with `<iframe>`s, as we'll discuss below, but this doesn't mean that you shouldn't use them in your websites — it just requires some knowledge and careful thinking. Let's explore the code in a bit more detail. Say you wanted to include the MDN glossary on one of your web pages — you could try something like this:
Before diving into using `<iframe>` elements, there are some security concerns to be aware of.
Say you wanted to include the MDN glossary on one of your web pages using the {{htmlelement("iframe")}} element, you might try something like the next code example.
If you were to do add the code below into one of your pages, you might be surprised to see an error message instead of the glossary page:

```html
<head>
Expand All @@ -234,7 +240,15 @@ There are some serious [Security concerns](#security_concerns) to consider with
</body>
```

This example includes the basic essentials needed to use an `<iframe>`:
If you have a look at your browser's console, you'll see an error message like the following:

```
Refused to display 'https://developer.mozilla.org/' in a frame because it set 'X-Frame-Options' to 'deny'.
```

The [Security](#security_concerns) section below goes into more detail about why you see this error, but first, let's have a look at what our code is doing.

The example includes the bare essentials needed to use an `<iframe>`:

- [`border: none`](/en-US/docs/Web/CSS/border)
- : If used, the `<iframe>` is displayed without a surrounding border. Otherwise, by default, browsers display the `<iframe>` with a surrounding border (which is generally undesirable).
Expand Down Expand Up @@ -284,7 +298,7 @@ HTTPS-enabling your site requires a special security certificate to be installed

You want to give attackers as little power as you can to do bad things on your website, therefore you should give embedded content _only the permissions needed for doing its job._ Of course, this applies to your own content, too. A container for code where it can be used appropriately — or for testing — but can't cause any harm to the rest of the codebase (either accidental or malicious) is called a [sandbox](<https://en.wikipedia.org/wiki/Sandbox_(computer_security)>).

Unsandboxed content can do way too much (executing JavaScript, submitting forms, popup windows, etc.) By default, you should impose all available restrictions by using the `sandbox` attribute with no parameters, as shown in our previous example.
Content that's not sandboxed may be able to execute JavaScript, submit forms, trigger popup windows, etc. By default, you should impose all available restrictions by using the `sandbox` attribute with no parameters, as shown in our previous example.

If absolutely required, you can add permissions back one by one (inside the `sandbox=""` attribute value) — see the {{htmlattrxref('sandbox','iframe')}} reference entry for all the available options. One important note is that you should _never_ add both `allow-scripts` and `allow-same-origin` to your `sandbox` attribute — in that case, the embedded content could bypass the [Same-origin policy](/en-US/docs/Glossary/Same-origin_policy) that stops sites from executing scripts, and use JavaScript to turn off sandboxing altogether.

Expand Down

0 comments on commit 2b9c5bb

Please sign in to comment.