- Notifications
You must be signed in to change notification settings - Fork228
onload and onerror#393
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Merged
Uh oh!
There was an error while loading.Please reload this page.
Merged
Changes fromall commits
Commits
Show all changes
35 commits Select commitHold shift + click to select a range
0e8551e
WIP
dbritto-dev33b4a34
WIP
dbritto-dev1b3ea1c
WIP
dbritto-devd03b123
Minor changes
dbritto-dev63c99ed
Minor changes
dbritto-deve4319a3
Minor changes
dbritto-dev64e55f6
numeracion en 117
joaquinelio75d2e1b
Update 2-ui/5-loading/03-onload-onerror/article.md
dbritto-devf602cc6
Update 2-ui/5-loading/03-onload-onerror/article.md
dbritto-dev381618f
Update 2-ui/5-loading/03-onload-onerror/article.md
dbritto-deva2a972f
Update 2-ui/5-loading/03-onload-onerror/article.md
dbritto-deva48b291
Update 2-ui/5-loading/03-onload-onerror/article.md
dbritto-devc772da4
Update 2-ui/5-loading/03-onload-onerror/article.md
dbritto-dev22a7032
Update 2-ui/5-loading/03-onload-onerror/article.md
dbritto-dev59de9de
Minor changes
dbritto-dev1c213ea
Merge branch 'onload-onerror' of github.com:danilobrinu/es.javascript…
dbritto-dev67400ab
Update 2-ui/5-loading/03-onload-onerror/article.md
dbritto-dev107e42c
Merge branch 'onload-onerror' of github.com:danilobrinu/es.javascript…
dbritto-devd815df0
Minor changes
dbritto-deva5a61d5
Minor changes
dbritto-dev6b8ffa5
Update 2-ui/5-loading/03-onload-onerror/article.md
dbritto-dev22c3bb4
Update 2-ui/5-loading/03-onload-onerror/article.md
dbritto-deva040bad
Update 2-ui/5-loading/03-onload-onerror/article.md
dbritto-dev6c7b486
Update 2-ui/5-loading/03-onload-onerror/article.md
dbritto-devc8e731a
Update 2-ui/5-loading/03-onload-onerror/article.md
dbritto-dev465f59d
Update 2-ui/5-loading/03-onload-onerror/article.md
dbritto-dev2c1c826
Update 2-ui/5-loading/03-onload-onerror/article.md
dbritto-devbcfbdc2
Update 2-ui/5-loading/03-onload-onerror/article.md
dbritto-dev294e010
Update 2-ui/5-loading/03-onload-onerror/article.md
dbritto-dev3a289ba
Update 2-ui/5-loading/03-onload-onerror/article.md
dbritto-devbc1d411
Update 2-ui/5-loading/03-onload-onerror/article.md
dbritto-dev62027d7
Update 2-ui/5-loading/03-onload-onerror/article.md
dbritto-devf18878d
Update 2-ui/5-loading/03-onload-onerror/article.md
dbritto-deva3c9011
Minor changes
dbritto-dev24bea0b
Merge branch 'onload-onerror' of github.com:danilobrinu/es.javascript…
dbritto-devFile filter
Filter by extension
Conversations
Failed to load comments.
Loading
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Jump to file
Failed to load files.
Loading
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
10 changes: 5 additions & 5 deletions2-ui/5-loading/03-onload-onerror/1-load-img-callback/solution.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
El algoritmo: | ||
1.Crear una`img`para cada fuente. | ||
2.Agregar los eventos`onload/onerror`para cada imágen. | ||
3.Incrementar el contador cuando el evento`onload`o el evento`onerror`se dispare. | ||
4.Cuando el valor del contador es igual a la cantidad de fuentes, hemos terminado: `callback()`. |
22 changes: 11 additions & 11 deletions2-ui/5-loading/03-onload-onerror/1-load-img-callback/task.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
144 changes: 72 additions & 72 deletions2-ui/5-loading/03-onload-onerror/article.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,187 +1,187 @@ | ||
#Carga de recursos: onloady onerror | ||
El navegador nos permite hacer seguimiento de la carga de recursos externos: scripts, iframes,imagenes y más. | ||
Hay dos eventos para eso: | ||
- `onload` --cuando cargó exitosamente, | ||
- `onerror` --cuando unerrorha ocurrido. | ||
##Cargando un script | ||
Digamos que tenemos que cargar un script de terceros y llamar una función que se encuentra dentro. | ||
Podemos cargarlo dinámicamente de esta manera: | ||
```js | ||
let script = document.createElement("script"); | ||
dbritto-dev marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
script.src = "my.js"; | ||
document.head.append(script); | ||
``` | ||
...pero ¿cómo podemos ejecutar la función que esta dentro delscript?Necesitamos esperar hasta que elscripthaya cargado, y solo después podemos llamarlo. | ||
```smart | ||
Para nuestrosscriptspodemos usar[JavaScript modules](info:modules)aquí, pero no está adoptado ampliamente por bibliotecas de terceros. | ||
``` | ||
### script.onload | ||
El evento`load`se dispara después de que scriptsea cargado y ejecutado. | ||
Por ejemplo: | ||
```js run untrusted | ||
let script = document.createElement('script'); | ||
//podemos cargar cualquier script desde cualquier dominio | ||
script.src = "https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.3.0/lodash.js" | ||
document.head.append(script); | ||
*!* | ||
script.onload = function() { | ||
//el scriptcrea una función de ayuda "_" | ||
alert(_); //la función está disponible | ||
}; | ||
*/!* | ||
``` | ||
Entonces en `onload`podemos usarvariables,ejecutar funciones, etc. | ||
...¿y si la carga falla? Por ejemplo:nohay talscript (error 404)en el servidor o el servidor está caído (no diponible). | ||
### script.onerror | ||
Los errores que ocurren durante la carga de unscriptpueden ser rastreados en el evento`error`. | ||
Por ejemplo, hagamos una petición a unscriptque no existe: | ||
```js run | ||
let script = document.createElement('script'); | ||
script.src = "https://example.com/404.js"; // nohay tal script | ||
document.head.append(script); | ||
*!* | ||
script.onerror = function() { | ||
alert("Erroral cargar" + this.src); // Erroral cargar https://example.com/404.js | ||
}; | ||
*/!* | ||
``` | ||
Por favor nota que como no podemos obtener detalles delerrorHTTP aquí, no podemos saber iffue unerror 404o algo diferente. Solo el error de carga. | ||
```warn | ||
Los eventos`onload/onerror`rastrean solamente la carga de ellos mismos. | ||
Los errores que pueden ocurrir durante el procesamiento y ejecución están fuera del alcance para esos eventos. Eso es: si un scriptes cargado de manera exitosa, incluso si tiene errores de programación adentro, el evento `onload` se dispara. Para rastrear los errores delscriptun puede usar el manejador global`window.onerror`; | ||
``` | ||
##Otros recursos | ||
Los eventos`load`y `error`también funcionan para otros recursos, básicamente para cualquiera que tenga una`src` externa. | ||
Por ejemplo: | ||
```js run | ||
let img = document.createElement("img"); | ||
img.src = "https://js.cx/clipart/train.gif"; // (*) | ||
img.onload = function() { | ||
alert(`Image loaded, size ${img.width}x${img.height}`); | ||
}; | ||
img.onerror = function() { | ||
alert("Error occurred while loading image"); | ||
}; | ||
``` | ||
Sin embargo, hay algunas notas: | ||
-La mayoría de recursos empiezan a cargarse cuando son agregados al documento. Pero `<img>`es una excepción, comienza la carga cuando obtiene una fuente ".src" `(*)`. | ||
-Para `<iframe>`,el evento`iframe.onload`se dispara cuando el iframeha terminado de cargar, tanto para una carga exitosa como en caso de un error. | ||
Esto es por razones históricas. | ||
##Política de origen cruzado | ||
Hay una regla: losscriptsde un sitio no pueden acceder al contenido de otro sitio. Por ejemplo: un scriptde `https://facebook.com`no puede leer la bandeja de correos del usuario en `https://gmail.com`. | ||
O para ser más precisos, un origen (el trío dominio/puerto/protocolo) no puede acceder al contenido de otro. Entonces, incluso si tenemos un sub-dominio o solo un puerto distinto, son considerados origenes diferentes sin acceso al otro. | ||
Esta regla también afecta a recursos de otros dominios. | ||
Si usamos unscriptde otro dominio y tiene un error, no podemos obtener detalles del error. | ||
Por ejemplo, tomemos unscript `error.js`que consta de un única llamada a una función (con errores). | ||
```js | ||
// 📁 error.js | ||
noSuchFunction(); | ||
``` | ||
Ahora cargalo desde el mismo sitio donde esta alojado: | ||
```html run height=0 | ||
<script> | ||
window.onerror = function(message, url, line, col, errorObj) { | ||
alert(`${message}\n${url}, ${line}:${col}`); | ||
}; | ||
</script> | ||
<script src="/article/onload-onerror/crossorigin/error.js"></script> | ||
``` | ||
Podemos ver un buen reporte de error, como este: | ||
``` | ||
Uncaught ReferenceError: noSuchFunction is not defined | ||
https://javascript.info/article/onload-onerror/crossorigin/error.js, 1:1 | ||
``` | ||
Ahora carguemos el mismoscriptdesde otro dominio: | ||
```html run height=0 | ||
<script> | ||
window.onerror = function(message, url, line, col, errorObj) { | ||
alert(`${message}\n${url}, ${line}:${col}`); | ||
}; | ||
</script> | ||
<script src="https://cors.javascript.info/article/onload-onerror/crossorigin/error.js"></script> | ||
``` | ||
El reporte es diferente, como este: | ||
``` | ||
Script error. | ||
, 0:0 | ||
``` | ||
Los detalles pueden variar dependiendo del navegador, pero la ideaes la misma: cualquier información sobre las partes internas de unscript,incluyendo el rastreo de la pila de errores, se oculta. Exactamente porque es de otro dominio. | ||
¿Por qué necesitamos detalles de error? | ||
Hay muchos servicios (y podemos construir uno nuestro) que escuchan los errores globales usando `window.onerror`,guardan los errores y proveen una interfaz para acceder a ellos y analizarlos. Eso es grandioso ya que podemos ver los errores originales ocasionados por nuestros usuarios. Pero si el scriptviene desde otro origen no hay mucha información sobre los errores como acabamos de ver. | ||
También se aplican políticas similares de origen cruzado (CORS) a otros tipos de recursos. | ||
**Para permitir el accesso de origen cruzado, la etiqueta`<script>`necesita tener el atributo`crossorigin`, además el servidor remoto debe proporcionar cabeceras especiales.** | ||
Hay 3 niveles de acceso de origen cruzado: | ||
1. **Sin el atributo`crossorigin`** --acceso prohibido. | ||
2. **`crossorigin="anonymous"`** --acceso permitido si el servidor responde con la cabecera `Access-Control-Allow-Origin`con `*`o nuestro origen. El navegador no envía la información de la autorización ycookiesal servidor remoto. | ||
3. **`crossorigin="use-credentials"`** --acceso permitido si el servidor envia de vuelta la cabecera`Access-Control-Allow-Origin`con nuestro origen y `Access-Control-Allow-Credentials: true`.El navegador envía la información de la autorización y lascookiesal servidor remoto. | ||
```smart | ||
Puedes leer más sobre accesos de origen cruzado en el capítulo<info:fetch-crossorigin>.Este describe el método`fetch`para requerimientos de red, pero la política es exactamente la misma. | ||
Cosas como las "cookies"estan fuera de nuestro alcance, pero podemos leer sobre ellas en <info:cookie>. | ||
``` | ||
En nuetro caso no teníamos ningún atributo de origen cruzado (`cross-origin`). Por lo que se prohibió el acceso de origen cruzado. Vamos a agregarlo. | ||
Podemos elegir entre`"anonymous"` (nose envian las cookies, una sola cabecera esa necesaria en el lado del servidor) y `"use-credentials"` (envias las cookies, dos cabeceras son necesarias en el lado del servidor). | ||
dbritto-dev marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
Si no nos importan las `cookies`, entonces `"anonymous"`es el camino a seguir: | ||
```html run height=0 | ||
<script> | ||
@@ -192,15 +192,15 @@ window.onerror = function(message, url, line, col, errorObj) { | ||
<script *!*crossorigin="anonymous"*/!* src="https://cors.javascript.info/article/onload-onerror/crossorigin/error.js"></script> | ||
``` | ||
Ahora, asumiendo que el servidor brinda una cabecera`Access-Control-Allow-Origin`, todo está bien. Podemos tener el reporte completo del error. | ||
##Resumen | ||
Las imágenes`<img>`,estilos externos, scriptsy otros recursos proveen los eventos`load`y `error`para rastrear sus cargas: | ||
- `load`se ejecuta cuando la carga ha sido exitosa, | ||
- `error`se ejecuta cuando una carga ha fallado. | ||
La única excepción es el`<iframe>`:por razones históricas siempre dispara el evento`load`,incluso si no encontró la página. | ||
El evento`readystatechange`también funciona para recursos, pero es muy poco usado debido a que los eventos`load/error`son mas simples. |
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.