{.section-title.accent.text-primary}
# Scripting internals

Internally, scripts are always loaded inside `iframes`.

You can load a script:

1. Using the [`script` property in your map properties](scripting.md#adding-a-script-in-the-map)
2. or from an iframe [opened as a co-website](scripting.md#adding-a-script-in-an-iframe) or [embedded in the map](website-in-map.md#allowing-the-scripting-api-in-your-iframe)

## Script restrictions

If you load a script using the `script` property in your map properties (solution 1), you need to understand that
WorkAdventure will generate an iframe, and will load the script inside this iframe.

Things you should know:

{.alert.alert-warning}
The [iframe is sandboxed](https://blog.dareboost.com/en/2015/07/securing-iframe-sandbox-attribute/)

This means that the iframe is generated with:

```
<iframe src="..." sandbox="allow-scripts allow-top-navigation-by-user-activation" />
```

Such an iframe has restrictions. In particular, it does NOT have an origin.
Because it has no origin, XHR requests cannot be made from those scripts.

If you absolutely need to make a request to an external server from your script, you can:

- use websockets (that are not subject to CORS restrictions)
- or load the script inside an embedded iframe (that you hide somewhere on the map)

## Script, modules and CORS issues

If you load a script using the `script` property in your map properties (solution 1), scripts are loaded by default with the
`type="module"` attribute. Because those scripts are [loaded as modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#applying_the_module_to_your_html),
they need to abide by the same-origin policy, so they are using CORS.

But because the iframe is sandboxed, the script does not have an origin. Therefore, the webserver hosting your script
will need to allow **all** origins with:

```
Access-Control-Allow-Origin: *
```
or alternatively:
```
Access-Control-Allow-Origin: null
```

This should not be a security concern if your website is only hosting static files. However, in the event the website
hosting the script is also hosting dynamic content, please be careful before allowing those headers on a site-wide basis.

If you cannot or do not want to allow CORS to all domains, there is an alternative: you can remove the `type="module"` attribute
from the script. The script will not be able to load modules anymore but will not be bound to the same origin policy anymore
so the `Access-Control-Allow-Origin` header is not needed anymore for this script.

To remove the `type="module"` attribute from the script, in your map properties, next to the `script` attribute,
add a `scriptDisableModuleSupport` boolean property and set this property to "checked".

![](images/script-disable-modules-support.png)
