Skip to content

Commit

Permalink
Document javascript: URLs (#35599)
Browse files Browse the repository at this point in the history
* Document javascript: URLs

* Apply suggestions from code review

Co-authored-by: Hamish Willee <[email protected]>

* Mention address bar

---------

Co-authored-by: Hamish Willee <[email protected]>
  • Loading branch information
Josh-Cena and hamishwillee committed Aug 27, 2024
1 parent fc9c6e0 commit 1a48b6a
Show file tree
Hide file tree
Showing 12 changed files with 164 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ let creating = browser.tabs.create(
For security reasons, in Firefox, this may not be a privileged URL. So passing any of the following URLs will fail:

- chrome: URLs
- javascript: URLs
- data: URLs
- [javascript: URLs](/en-US/docs/Web/URI/Schemes/javascript)
- [data: URLs](/en-US/docs/Web/URI/Schemes/data)
- file: URLs (i.e., files on the filesystem. However, to use a file packaged inside the extension, see below)
- privileged about: URLs (for example, `about:config`, `about:addons`, `about:debugging`). Non-privileged URLs (e.g., `about:blank`) are allowed.
- The New Tab page (`about:newtab`) can be opened if no value for URL is provided.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ let updating = browser.tabs.update(
For security reasons, in Firefox, this may not be a privileged URL. So passing any of the following URLs will fail, with {{WebExtAPIRef("runtime.lastError")}} being set to an error message:

- chrome: URLs
- javascript: URLs
- data: URLs
- [javascript: URLs](/en-US/docs/Web/URI/Schemes/javascript)
- [data: URLs](/en-US/docs/Web/URI/Schemes/data)
- file: URLs (i.e., files on the filesystem. However, to use a file packaged inside the extension, see below)
- privileged about: URLs (for example, `about:config`, `about:addons`, `about:debugging`, `about:newtab`). Non-privileged URLs (e.g., `about:blank`) are allowed.

Expand Down
2 changes: 1 addition & 1 deletion files/en-us/mozilla/firefox/releases/127/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This article provides information about the changes in Firefox 127 that affect d

### HTML

- `data:` and `javascript:` URLs are now forbidden in the [`href`](/en-US/docs/Web/HTML/Element/base#href) attribute of the `<base>` element ([Firefox bug 1850967](https://bugzil.la/1850967)).
- [`data:`](/en-US/docs/Web/URI/Schemes/data) and [`javascript:`](/en-US/docs/Web/URI/Schemes/javascript) URLs are now forbidden in the [`href`](/en-US/docs/Web/HTML/Element/base#href) attribute of the `<base>` element ([Firefox bug 1850967](https://bugzil.la/1850967)).

### CSS

Expand Down
4 changes: 2 additions & 2 deletions files/en-us/web/api/speculation_rules_api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -387,8 +387,8 @@ APIs that require the containing document's {{domxref("Document.visibilityState"
- Download links, i.e. {{htmlelement("a")}} and {{htmlelement("area")}} elements with the `download` attribute, will have their downloads delayed until prerendering has finished.
- No cross-site navigations: Any prerendering document that navigates to a different site will be immediately discarded before a request to that other site is sent.
- Restricted URLs: Prerendering documents cannot host non-HTTP(S) top-level URLs. Including the following URL types will cause the prerender to be immediately discarded:
- `javascript:` URLs
- `data:` URLs
- [`javascript:` URLs](/en-US/docs/Web/URI/Schemes/javascript)
- [`data:` URLs](/en-US/docs/Web/URI/Schemes/data)
- `blob:` URLs
- `about:` URLs, including `about:blank` and `about:srcdoc`
- Session storage: {{domxref("Window.sessionStorage")}} can be used, but the behavior is very specific, to avoid breaking sites that expect only one page to access the tab's session storage at a time. A prerendered page therefore starts out with a clone of the tab's session storage state from when it was created. Upon activation, the prerendered page's storage clone is discarded, and the tab's main storage state is used instead. Pages that use session storage can use the {{domxref("Document.prerenderingchange_event", "prerenderingchange")}} event to detect when this storage swap occurs.
Expand Down
2 changes: 1 addition & 1 deletion files/en-us/web/api/window/postmessage/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ The value of the `origin` property of the dispatched event is not affected by th

For IDN host names only, the value of the `origin` property is not consistently Unicode or punycode; for greatest compatibility check for both the IDN and punycode values when using this property if you expect messages from IDN sites. This value will eventually be consistently IDN, but for now you should handle both IDN and punycode forms.

The value of the `origin` property when the sending window contains a `javascript:` or `data:` URL is the origin of the script that loaded the URL.
The value of the `origin` property when the sending window contains a [`javascript:`](/en-US/docs/Web/URI/Schemes/javascript) or [`data:`](/en-US/docs/Web/URI/Schemes/data) URL is the origin of the script that loaded the URL.

### Using window\.postMessage in extensions {{Non-standard_inline}}

Expand Down
12 changes: 8 additions & 4 deletions files/en-us/web/html/element/a/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,18 @@ This element's attributes include the [global attributes](/en-US/docs/Web/HTML/G

- : The URL that the hyperlink points to. Links are not restricted to HTTP-based URLs — they can use any URL scheme supported by browsers:

- Sections of a page with document fragments
- Specific text portions with [text fragments](/en-US/docs/Web/URI/Fragment/Text_fragments)
- Pieces of media files with media fragments
- Telephone numbers with `tel:` URLs
- Email addresses with `mailto:` URLs
- SMS text messages with `sms:` URLs
- Executable code with [`javascript:` URLs](/en-US/docs/Web/URI/Schemes/javascript)
- While web browsers may not support other URL schemes, websites can with [`registerProtocolHandler()`](/en-US/docs/Web/API/Navigator/registerProtocolHandler)

Moreover other URL features can locate specific parts of the resource, including:

- Sections of a page with document fragments
- Specific text portions with [text fragments](/en-US/docs/Web/URI/Fragment/Text_fragments)
- Pieces of media files with media fragments

- `hreflang`
- : Hints at the human language of the linked URL. No built-in functionality. Allowed values are the same as [the global `lang` attribute](/en-US/docs/Web/HTML/Global_attributes/lang).
- `ping`
Expand Down Expand Up @@ -169,7 +173,7 @@ Assistive software has shortcuts to list all links on a page. However, strong li

### onclick events

Anchor elements are often abused as fake buttons by setting their `href` to `#` or `javascript:void(0)` to prevent the page from refreshing, then listening for their `click` events .
Anchor elements are often abused as fake buttons by setting their `href` to `#` or [`javascript:void(0)`](/en-US/docs/Web/URI/Schemes/javascript) to prevent the page from refreshing, then listening for their `click` events.

These bogus `href` values cause unexpected behavior when copying/dragging links, opening links in a new tab/window, bookmarking, or when JavaScript is loading, errors, or is disabled. They also convey incorrect semantics to assistive technologies, like screen readers.

Expand Down
2 changes: 1 addition & 1 deletion files/en-us/web/html/element/base/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ This element's attributes include the [global attributes](/en-US/docs/Web/HTML/G
- `href`
- : The base URL to be used throughout the document for relative URLs.
Absolute and relative URLs are allowed.
[`data:`](/en-US/docs/Web/URI/Schemes/data) and `javascript:` URLs are not allowed.
[`data:`](/en-US/docs/Web/URI/Schemes/data) and [`javascript:`](/en-US/docs/Web/URI/Schemes/javascript) URLs are not allowed.
- `target`

- : A **keyword** or **author-defined name** of the default {{Glossary("browsing context")}} to show the results of navigation from {{HTMLElement("a")}}, {{HTMLElement("area")}}, or {{HTMLElement("form")}} elements without explicit `target` attributes. The following keywords have special meanings:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ Relevant directives include the {{Glossary("fetch directive", "fetch directives"
The single quotes are required.
- `'unsafe-hashes'`
- : Allows enabling specific inline [event handlers](/en-US/docs/Web/Events/Event_handlers).
If you only need to allow inline event handlers and not inline {{HTMLElement("script")}} elements or `javascript:` URLs, this is a safer method than using the `unsafe-inline` expression.
If you only need to allow inline event handlers and not inline {{HTMLElement("script")}} elements or [`javascript:` URLs](/en-US/docs/Web/URI/Schemes/javascript), this is a safer method than using the `unsafe-inline` expression.
- `'unsafe-inline'`
- : Allows the use of inline resources, such as inline {{HTMLElement("script")}} elements, `javascript:` URLs, inline event handlers, and inline {{HTMLElement("style")}} elements.
- : Allows the use of inline resources, such as inline {{HTMLElement("script")}} elements, [`javascript:` URLs](/en-US/docs/Web/URI/Schemes/javascript), inline event handlers, and inline {{HTMLElement("style")}} elements.
The single quotes are required.
- `'none'`
- : Refers to the empty set; that is, no URLs match.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ This is a bit longer than wrapping the function expression in parentheses, which

### JavaScript URIs

When a browser follows a `javascript:` URI, it evaluates the code in the URI
When a browser follows a [`javascript:` URI](/en-US/docs/Web/URI/Schemes/javascript), it evaluates the code in the URI
and then replaces the contents of the page with the returned value, unless the returned
value is {{jsxref("undefined")}}. The `void` operator can be used to return
`undefined`. For example:
Expand Down
2 changes: 1 addition & 1 deletion files/en-us/web/security/same-origin_policy/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ The following table gives examples of origin comparisons with the URL `http://st

### Inherited origins

Scripts executed from pages with an `about:blank` or `javascript:` URL inherit the origin of the document containing that URL, since these types of URLs do not contain information about an origin server.
Scripts executed from pages with an `about:blank` or [`javascript:` URL](/en-US/docs/Web/URI/Schemes/javascript) inherit the origin of the document containing that URL, since these types of URLs do not contain information about an origin server.

For example, `about:blank` is often used as a URL of new, empty popup windows into which the parent script writes content (e.g. via the {{domxref("Window.open()")}} mechanism). If this popup also contains JavaScript, that script would inherit the same origin as the script that created it.

Expand Down
2 changes: 1 addition & 1 deletion files/en-us/web/uri/schemes/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ protocol:
- : {{Glossary("FTP","File Transfer Protocol")}}
- `http` / `https`
- : Hyper text transfer protocol (Secure) ({{glossary("HTTP")}}/{{glossary("HTTPS")}})
- `javascript`
- [`javascript`](/en-US/docs/Web/URI/Schemes/javascript)
- : URL-embedded JavaScript code
- `mailto`
- : Electronic mail address
Expand Down
142 changes: 142 additions & 0 deletions files/en-us/web/uri/schemes/javascript/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
---
title: "javascript: URLs"
slug: Web/URI/Schemes/javascript
page-type: guide
spec-urls: https://html.spec.whatwg.org/multipage/browsing-the-web.html#the-javascript:-url-special-case
---

{{QuickLinksWithSubpages("/en-US/docs/Web/URI")}}

> [!WARNING]
> Using `javascript:` URLs on the web is discouraged as it may lead to execution of arbitrary code, similar to the ramifications of using [`eval()`](/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval). It may also reduce {{glossary("accessibility")}} because it deviates from normal link behavior.
**JavaScript URLs**, URLs prefixed with the `javascript:` scheme, are used as fake navigation targets that execute JavaScript when the browser attempts to navigate. If the URL evaluates to a string, it is treated as HTML and rendered by the browser.

## Syntax

JavaScript URLs start with the `javascript:` scheme and are followed by JavaScript code. The code will be parsed as a script.

```url
javascript:<script>
```

## Description

`javascript:` URLs can be used anywhere a URL is a navigation target. This includes, but is not limited to:

- The [`href`](/en-US/docs/Web/HTML/Element/a#href) attribute of an `<a>` or `<area>` element.
- The [`action`](/en-US/docs/Web/HTML/Element/form#action) attribute of a `<form>` element.
- The [`src`](/en-US/docs/Web/HTML/Element/iframe#src) attribute of an `<iframe>` element.
- The [`window.location`](/en-US/docs/Web/API/Window/location) JavaScript property.
- The browser address bar itself.

> [!NOTE]
> Some other contexts that use URLs, such as the [`href`](/en-US/docs/Web/HTML/Element/link#href) attribute of `<link>` elements, do not allow `javascript:` URLs, because they are resource locations, not navigation targets. For these cases, if you want to write JavaScript inline, use [`data:`](/en-US/docs/Web/URI/Schemes/data) URLs with the `text/javascript` MIME type.
When a browser attempts to navigate to such a location, it parses and executes the script body. The script may have a _completion value_ (not a return value), which is the same value if the script were executed with [`eval()`](/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval). If the last statement is an [expression](/en-US/docs/Web/JavaScript/Reference/Statements/Expression_statement), the completion value is the value of that expression. If this completion value is a string, that string is treated as an HTML document and the browser navigates to a new document with that content, using the same URL as the current page. No history entry is created. If the completion value is not a string, the browser only executes the code and does not navigate. Therefore, it's often recommended that if the script ends with a function call like `javascript:foo()`, you should prefix it with {{jsxref("Operators/void", "void")}} to prevent accidental navigation if the function happens to return a string.

`javascript:` navigation may be blocked by [content security policy](/en-US/docs/Web/HTTP/CSP) settings, in particular {{CSP("script-src")}}.

## Examples

### Using `javascript:` URLs as href targets

In this example, the `href` attribute of an `<a>` element is set to a `javascript:` URL that alerts a message when clicked:

```html example-bad
<a href="javascript:alert('Hello, world!')">Click me</a>
```

Because {{domxref("Window/alert", "alert()")}} returns `undefined`, the browser does not navigate to a new page. This is a bad practice because the link is actually not a hyperlink. Consider making it a button instead:

```html example-good
<button id="btn">Click me</button>
<script>
document.getElementById("btn").addEventListener("click", () => {
alert("Hello, world!");
});
</script>
```

In this example, the `href` attribute of an `<a>` element is set to a `javascript:` URL that navigates to a new page with the content "Hello, world!":

```html example-bad
<a href="javascript:pageContent">Click me</a>
<script>
// Use a var so it becomes a global variable and can be read elsewhere
var pageContent = "Hello, world!";
</script>
```

Note that because `javascript:` URLs do not create history entries, there's no way to go back to the previous page without refreshing.

### Using `javascript:` URLs as form actions

In this example, the `action` attribute of a `<form>` element is set to a `javascript:` URL that alerts a message when submitted:

```html example-bad
<form action="javascript:alert(myInput.value)">
<input id="myInput" />
<input type="submit" value="Submit" />
</form>
```

Instead of doing this, consider listening for the form's `submit` event and handling it with JavaScript:

```html example-good
<form id="myForm">
<input id="myInput" />
<input type="submit" value="Submit" />
</form>
<script>
document.getElementById("myForm").addEventListener("submit", (event) => {
event.preventDefault();
alert(document.getElementById("myInput").value);
});
</script>
```

### Using `javascript:` URLs as iframe sources

In this example, the `src` attribute of an `<iframe>` element is set to a `javascript:` URL that navigates to a new page with the content "Hello, world!":

```html example-bad
<iframe src="javascript:pageContent"></iframe>
<script>
// Use a var so it becomes a global variable and can be read elsewhere
var pageContent = "Hello, world!";
</script>
```

Instead of doing this, consider setting the `srcdoc` attribute instead:

```html example-good
<iframe id="myFrame"></iframe>
<script>
document.getElementById("myFrame").srcdoc = "Hello, world!";
</script>
```

### Using `javascript:` URLs with window.location

In this example, the `window.location` property is set to a `javascript:` URL that navigates to a new page with the content "Hello, world!":

```js example-bad
window.location = "javascript:'Hello world!'";
```

Instead of doing this, consider using [DOM APIs](/en-US/docs/Web/API/HTML_DOM_API) to modify the page content. For example:

```js example-good
document.body.textContent = "Hello, world!";
```

## Specifications

{{Specifications}}

## See also

- [URIs](/en-US/docs/Web/URI)
- [Content Security Policy (CSP)](/en-US/docs/Web/HTTP/CSP)
- [IANA list of URI schemes](https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml)

0 comments on commit 1a48b6a

Please sign in to comment.