Informe "Error de tipo no detectado (en promesa): Error de red al intentar recuperar el recurso". Solución de error

Utilicé la promesa, pero se informó un error no detectado (en la promesa) durante el uso. Esta es la primera vez que encuentro este error, así que lo registré aquí para facilitar la solución del problema en el futuro.
Insertar descripción de la imagen aquí

Uncaught (in promise) TypeError: NetworkError when attempting to fetch resource.Generalmente se producen errores al utilizar la API de recuperación para iniciar una solicitud de red y la excepción se produce cuando el recurso no se puede obtener con éxito. Para resolver este problema, puede probar los siguientes métodos:

  1. Compruebe si la conexión de red es normal. Si la red es inestable o hay otros problemas, es posible que la API de recuperación no pueda obtener recursos correctamente, lo que provoca esta excepción.

  2. Compruebe si la dirección de la solicitud es correcta. Si la dirección de solicitud es incorrecta o no existe, la API de recuperación tampoco podrá obtener el recurso, lo que provocará esta excepción.

  3. Compruebe si hay problemas entre dominios. En algunos casos, los navegadores prohibirán las solicitudes entre dominios, por lo que es necesario configurar CORS (intercambio de recursos entre orígenes) en el servidor para permitir solicitudes entre dominios.

  4. Agregue lógica de manejo de errores en la API de recuperación, como usar el método catch() para detectar excepciones y realizar el manejo de errores adecuado.


Este error suele deberse a la imposibilidad de obtener el recurso solicitado. Puede intentar agregar .catch() entre el método d3.json() y su función de devolución de llamada para un mejor manejo de excepciones. Además, para evitar problemas de solicitud entre dominios, se recomienda colocar el archivo de mapa en el mismo directorio que el archivo HTML y utilizar rutas relativas como referencia.

Antes de cambiar

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Map Visualization</title>
    <style>
        #map {
    
    
            width: 800px;
            height: 600px;
            border: solid 1px #ccc;
        }
    </style>
</head>
<body>
    <div id="map"></div>
    <script src="https://d3js.org/d3.v5.min.js"></script>
    <script src="https://d3js.org/topojson.v3.min.js"></script>
    <script>
	// 定义地图容器宽高
var width = 800;
var height = 600;

// 创建SVG元素
var svg = d3.select("#map")
            .append("svg")
            .attr("width", width)
            .attr("height", height);

// 创建投影函数
var projection = d3.geoMercator()
                   .center([105, 38])
                   .scale(750)
                   .translate([width/2, height/2]);

// 创建路径生成器
var path = d3.geoPath()
             .projection(projection);

// 加载中国地图数据
d3.json("china.json").then(function(json) {
    
    
    // 将TopoJSON转换为GeoJSON
    var features = topojson.feature(json, json.objects.china).features;
  
    // 绘制地图
    svg.selectAll("path")
       .data(features)
       .enter()
       .append("path")
       .attr("d", path)
       .style("fill", "#ccc")
       .style("stroke", "#fff")
       .style("stroke-width", 1);
  
    // 处理用户交互
    svg.selectAll("path")
       .on("mouseover", function(d) {
    
    
           d3.select(this).style("opacity", "0.7");
       })
       .on("mouseout", function(d) {
    
    
           d3.select(this).style("opacity", "1");
       })
       .on("click", function(d) {
    
    
           var region = d.properties.name; // 获取区域名称
           var color = prompt("请输入" + region + "的颜色:"); // 弹出输入框获取用户输入的颜色
           d3.select(this).style("fill", color); // 修改区域颜色
       });
});

	</script>
</body>
</html>

despues del cambio

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Map Visualization</title>
    <style>
        #map {
    
    
            width: 800px;
            height: 600px;
            border: solid 1px #ccc;
        }
    </style>
</head>
<body>
    <div id="map"></div>
    <script src="https://d3js.org/d3.v5.min.js"></script>
    <script src="https://d3js.org/topojson.v3.min.js"></script>
    <script>
	// 定义地图容器宽高
    var width = 800;
    var height = 600;

    // 创建SVG元素
    var svg = d3.select("#map")
                .append("svg")
                .attr("width", width)
                .attr("height", height);

    // 创建投影函数
    var projection = d3.geoMercator()
                       .center([105, 38])
                       .scale(750)
                       .translate([width/2, height/2]);

    // 创建路径生成器
    var path = d3.geoPath()
                 .projection(projection);

    // 加载中国地图数据
    d3.json("china.json").then(function(json) {
    
    
        // 将TopoJSON转换为GeoJSON
        var features = topojson.feature(json, json.objects.china).features;

        // 绘制地图
        svg.selectAll("path")
           .data(features)
           .enter()
           .append("path")
           .attr("d", path)
           .style("fill", "#ccc")
           .style("stroke", "#fff")
           .style("stroke-width", 1)
           .on("mouseover", function(d) {
    
    
               d3.select(this).style("opacity", "0.7");
           })
           .on("mouseout", function(d) {
    
    
               d3.select(this).style("opacity", "1");
           })
           .on("click", function(d) {
    
    
               var region = d.properties.name; // 获取区域名称
               var color = prompt("请输入" + region + "的颜色:"); // 弹出输入框获取用户输入的颜色
               d3.select(this).style("fill", color); // 修改区域颜色
           });
    }).catch(function(error){
    
    
        console.log("数据加载失败:" + error);
    });
	</script>
</body>
</html>


El principal problema es que se agregó un error al error de impresión, pero aún así se informó un error: falló la carga de datos:TypeError: NetworkError when attempting to fetch resource.

catch(function(error){
    
    
        console.log("数据加载失败:" + error);
    });

Emm, así que necesito pensarlo de nuevo.


Primero entendamos qué es cors.

El intercambio de recursos entre orígenes (CORS) (o traducido coloquialmente como intercambio de recursos entre orígenes) es un mecanismo que utiliza encabezados HTTP adicionales para indicarle al navegador que permita que una aplicación web que se ejecuta en un origen acceda a un origen diferente.Recursos seleccionados. Cuando una aplicación web inicia una solicitud HTTP que es diferente de su propio origen (dominio, protocolo y puerto), inicia una solicitud HTTP de origen cruzado.

Un ejemplo de una solicitud HTTP de origen cruzado: el código JavaScript que se ejecuta en http://domain-a.com usa XMLHttpRequest para iniciar una solicitud a https://domain-b.com/data.json.

Por razones de seguridad, los navegadores restringen las solicitudes HTTP de origen cruzado iniciadas dentro de scripts. Por ejemplo, XMLHttpRequest y Fetch API siguen la misma política de origen. Esto significa que las aplicaciones web que utilizan estas API solo pueden solicitar recursos HTTP del mismo dominio donde se carga la aplicación, a menos que la respuesta contenga los encabezados de respuesta CORS correctos.
Insertar descripción de la imagen aquí

El mecanismo de intercambio de recursos entre orígenes (CORS) permite a los servidores de aplicaciones web realizar un control de acceso entre orígenes para que la transmisión de datos entre orígenes se pueda realizar de forma segura. Los navegadores modernos admiten el uso de CORS dentro de contenedores API (como XMLHttpRequest o Fetch) para reducir los riesgos que plantean las solicitudes HTTP de origen cruzado.


Descripción funcional

El estándar de intercambio de recursos entre orígenes agrega un nuevo conjunto de campos de encabezado HTTP que permiten al servidor declarar qué sitios de origen tienen permiso para acceder a qué recursos a través del navegador. Además, la especificación requiere que para aquellos métodos de solicitud HTTP que puedan tener efectos secundarios en los datos del servidor (especialmente solicitudes HTTP distintas de GET o solicitudes POST con ciertos tipos MIME), el navegador primero debe usar el método OPTIONS para iniciar una solicitud de verificación previa. (solicitud de verificación previa) para saber si el servidor permite la solicitud de origen cruzado. Una vez que el servidor confirma el permiso, inicia la solicitud HTTP real. Al devolver la solicitud de verificación previa, el servidor también puede notificar al cliente si necesita llevar credenciales de identidad (incluidas cookies y datos relacionados con la autenticación HTTP).

Una solicitud CORS fallida generará un error, pero por razones de seguridad, es imposible saber exactamente qué salió mal a nivel de código JavaScript. Sólo puedes consultar la consola de tu navegador para ver exactamente dónde ocurrió el error.

El siguiente contenido discutirá escenarios relacionados y analizará los campos de encabezado HTTP involucrados en este mecanismo.

Varios escenarios de control de acceso

Aquí, utilizamos tres escenarios para explicar cómo funciona el mecanismo de intercambio de recursos entre orígenes. Todos estos ejemplos utilizan el objeto XMLHttpRequest.

Todos los fragmentos de código JavaScript de este artículo están disponibles en http://arunranga.com/examples/access-control/. Además, utilice un navegador que admita XMLHttpRequest de origen cruzado para acceder a la dirección y ver los resultados de ejecución reales del código.

Para obtener información sobre la compatibilidad del lado del servidor para compartir recursos entre orígenes, consulte este artículo: Server-Side_Access_Control (CORS).
petición sencilla

Algunas solicitudes no activarán solicitudes de verificación previa de CORS. Este artículo llama a dicha solicitud una "solicitud simple"; tenga en cuenta que este término no pertenece a la especificación Fetch (donde se define CORS). Una solicitud se considera "solicitud simple" si cumple con todas las condiciones siguientes:

Utilice uno de los siguientes métodos:

  1. CONSEGUIR
  2. CABEZA
  3. CORREO

Además de los campos de encabezado establecidos automáticamente por el agente de usuario (como Conexión, Agente de usuario) y otros encabezados definidos como nombres de encabezado deshabilitados en la especificación Fetch, los campos que pueden configurarse manualmente son el conjunto de CORS-safe campos de encabezado definidos por la especificación Fetch.

El conjunto es:
Aceptar
Aceptar-
Contenido de idioma-Tipo de contenido de idioma
(es necesario tener en cuenta restricciones adicionales)
DPR
Enlace descendente
Guardar-Datos
Viewport-Width El valor de
Ancho
Tipo de contenido se limita a uno de los tres siguientes:

  1. Texto sin formato
  2. datos multiparte/formulario
  3. aplicación/x-www-formulario-urlencoded

Nota: Estas solicitudes entre sitios no son diferentes de otras solicitudes entre sitios realizadas por el navegador. Si el servidor no devuelve los encabezados de respuesta correctos, el solicitante no recibirá ningún dato. Por lo tanto, los sitios que no permiten solicitudes entre sitios no deben preocuparse por esta nueva función de control de acceso HTTP.

Supongamos que la aplicación web del sitio http://foo.example quiere acceder a los recursos de http://bar.other. La página web en http://foo.example puede contener código JavaScript similar al siguiente:

var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/public-data/';
    
function callOtherDomain() {
    
    
  if(invocation) {
    
        
    invocation.open('GET', url, true);
    invocation.onreadystatechange = handler;
    invocation.send(); 
  }
}

Los campos de encabezado CORS se utilizan entre el cliente y el servidor para manejar los permisos:
Insertar descripción de la imagen aquí

Vea el mensaje de solicitud y el mensaje de respuesta por separado:

GET /resources/public-data/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Referer: http://foo.example/examples/access-control/simpleXSInvocation.html
Origin: http://foo.example


HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2.0.61
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml

[XML Data]

Las líneas 1 a 10 son los encabezados de la solicitud. El campo del encabezado de la solicitud Origen en la línea 10 indica que la solicitud proviene de http://foo.example.

Las líneas 13 a 22 son respuestas del servidor de http://bar.other. La respuesta lleva el campo de encabezado de respuesta Access-Control-Allow-Origin (línea 16). El control de acceso más simple se puede lograr usando Origin y Access-Control-Allow-Origin. En este ejemplo, Access-Control-Allow-Origin: * devuelto por el servidor indica que cualquier dominio externo puede acceder al recurso. Si el servidor solo permite el acceso desde http://foo.example, el contenido de este campo de encabezado es el siguiente:

Control-de-acceso-permitir-origen: http://foo.example

Ahora, ningún otro dominio externo puede acceder a este recurso excepto http://foo.example (esta política está definida por el campo ORIGEN en el encabezado de la solicitud, consulte la línea 10). Access-Control-Allow-Origin debe ser * o contener el nombre de dominio especificado en el campo del encabezado Origen.

Solicitud de verificación previa

A diferencia de las solicitudes simples antes mencionadas, las "solicitudes que requieren verificación previa" requieren que primero se use el método OPCIONES para iniciar una solicitud de verificación previa al servidor para saber si el servidor permite la solicitud real. El uso de una "solicitud de verificación previa" puede evitar que las solicitudes entre dominios tengan efectos inesperados en los datos del usuario en el servidor.

La siguiente es una solicitud HTTP que necesita realizar una solicitud de verificación previa:

var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/post-here/';
var body = '<?xml version="1.0"?><person><name>Arun</name></person>';

function callOtherDomain(){
    
    
  if(invocation)
    {
    
    
      invocation.open('POST', url, true);
      invocation.setRequestHeader('X-PINGOTHER', 'pingpong');
      invocation.setRequestHeader('Content-Type', 'application/xml');
      invocation.onreadystatechange = handler;
      invocation.send(body);
    }
}

El código anterior utiliza una solicitud POST para enviar un documento XML, que contiene un campo de encabezado de solicitud personalizado (X-PINGOTHER: pingpong). Además, el tipo de contenido de la solicitud es aplicación/xml. Por lo tanto, la solicitud debe iniciar primero una "solicitud de verificación previa".

Insertar descripción de la imagen aquí

0.7,*;q=0.7
Connection: keep-alive
Origin: http://foo.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type


HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2.0.61 (Unix)
Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain
预检请求完成之后,发送实际请求:

POST /resources/post-here/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8                    
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
X-PINGOTHER: pingpong
Content-Type: text/xml; charset=UTF-8
Referer: http://foo.example/examples/preflightInvocation.html
Content-Length: 55
Origin: http://foo.example
Pragma: no-cache
Cache-Control: no-cache

<?xml version="1.0"?><person><name>Arun</name></person>


HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:40 GMT
Server: Apache/2.0.61 (Unix)
Access-Control-Allow-Origin: http://foo.example
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 235
Keep-Alive: timeout=2, max=99
Connection: Keep-Alive
Content-Type: text/plain

[Some GZIP'd payload]

El navegador ha detectado que las solicitudes realizadas desde JavaScript deben someterse a una verificación previa. En el mensaje anterior, vemos que las líneas 1 a 12 envían una "solicitud de verificación previa" utilizando el método OPCIONES. OPCIONES es un método definido en el protocolo HTTP/1.1 para obtener más información del servidor. Este método no tiene ningún impacto en los recursos del servidor. La solicitud de verificación previa también incluye los dos campos de encabezado siguientes:

Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type

El campo de encabezado Access-Control-Request-Method le dice al servidor que la solicitud real utilizará el método POST. El campo de encabezado Access-Control-Request-Headers le dice al servidor que la solicitud real llevará dos campos de encabezado de solicitud personalizados: X-PINGOTHER y Content-Type. En base a esto, el servidor decide si se permite la solicitud real.

Las líneas 14 a 26 son respuestas a solicitudes de verificación previa, lo que indica que el servidor aceptará solicitudes reales posteriores. Centrarse en las líneas 17 ~ 20:

Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400

El campo de encabezado Access-Control-Allow-Methods indica que el servidor permite al cliente iniciar solicitudes utilizando los métodos POST, GET y OPTIONS. Este campo es similar al encabezado de respuesta HTTP/1.1 Permitir:, pero su uso está limitado en escenarios que requieren control de acceso.

El campo de encabezado Access-Control-Allow-Headers indica que el servidor permite que los campos X-PINGOTHER y Content-Type se incluyan en la solicitud. Al igual que Access-Control-Allow-Methods, el valor de Access-Control-Allow-Headers es una lista separada por comas.

Finalmente, el campo de encabezado Access-Control-Max-Age indica que la respuesta es válida por 86400 segundos, que son 24 horas. Dentro del período de validez, el navegador no necesita iniciar nuevamente una solicitud de verificación previa para la misma solicitud. Tenga en cuenta que el propio navegador mantiene un tiempo máximo de validez. Si el valor de este campo de encabezado excede el tiempo máximo de validez, no tendrá efecto.
Solicitudes de verificación previa y redirecciones

La mayoría de los navegadores no admiten redireccionamientos para solicitudes de verificación previa. Si se produce una redirección para una solicitud de verificación previa, el navegador informará un error:

La solicitud se redirigió a 'https://example.com/foo', que no está
permitido para solicitudes entre orígenes que requieren una verificación previa.

La solicitud requiere una verificación previa, que no está permitida para seguir
la redirección entre orígenes

CORS originalmente requería este comportamiento, pero este requisito quedó obsoleto en revisiones posteriores.

Antes de que las implementaciones del navegador se pongan al día con las especificaciones, existen dos formas de evitar el comportamiento de notificación de errores anterior:

  1. Eliminar la redirección de solicitudes de verificación previa en el lado del servidor;
  2. Convierta la solicitud real en una solicitud simple.

Si los dos métodos anteriores son difíciles de lograr, todavía tenemos otros métodos:

  1. Realice una solicitud simple (usando Response.url o XHR.responseURL) para determinar qué dirección devolverá una solicitud de verificación previa real.
  2. Realice otra solicitud (una solicitud real), utilizando la URL obtenida en el paso anterior a través de Response.url o XMLHttpRequest.responseURL.

Sin embargo, este método no funcionará si la solicitud provocó una solicitud de verificación previa debido a la presencia del campo Autorización. Esta situación sólo puede ser cambiada por el servidor.

Solicitar con credenciales

Una característica interesante de XMLHttpRequest o Fetch con CORS es que las credenciales se pueden enviar en función de las cookies HTTP y la información de autenticación HTTP. En términos generales, los navegadores no envían información de credenciales para solicitudes XMLHttpRequest o Fetch de origen cruzado. Si desea enviar información de credenciales, debe configurar un indicador especial de XMLHttpRequest.

En este ejemplo, un script en http://foo.example inicia una solicitud GET a http://bar.other y establece Cookies:

var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/credentialed-content/';

function callOtherDomain(){
    
    
  if(invocation) {
    
    
    invocation.open('GET', url, true);
    invocation.withCredentials = true;
    invocation.onreadystatechange = handler;
    invocation.send();
  }
}

La línea 7 establece el indicador withCredentials de XMLHttpRequest en verdadero, enviando así cookies al servidor. Debido a que se trata de una solicitud GET simple, el navegador no inicia una "solicitud de verificación previa" para ella. Sin embargo, si la respuesta del lado del servidor no incluye Access-Control-Allow-Credentials: true, el navegador no devolverá el contenido de la respuesta al remitente de la solicitud.

Insertar descripción de la imagen aquí

Un ejemplo de interacción cliente-servidor es el siguiente:

GET /resources/access-control-with-credentials/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
Referer: http://foo.example/examples/credential.html
Origin: http://foo.example
Cookie: pageAccess=2


HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:34:52 GMT
Server: Apache/2
Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Credentials: true
Cache-Control: no-cache
Pragma: no-cache
Set-Cookie: pageAccess=3; expires=Wed, 31-Dec-2008 01:34:53 GMT
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 106
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain


[text/plain payload]

Aunque la información relacionada con las cookies se especifica en la línea 10, si Access-Control-Allow-Credentials: true (línea 17) falta en la respuesta de bar.other, el contenido de la respuesta no se devolverá al autor de la solicitud.
Solicitudes con credenciales y comodines

Access-Control-Allow-OriginEl servidor NO DEBE establecer el valor de "*" para solicitudes acompañadas de credenciales .

Esto se debe a que el encabezado de la solicitud contiene información de cookies. Si Access-Control-Allow-Originel valor es "*", la solicitud fallará. Y si Access-Control-Allow-Originel valor de se establece en http://foo.example, la solicitud se ejecutará correctamente.

Además, el encabezado de respuesta también incluye el campo Set-Cookie y se intenta modificar la cookie. Si la operación falla, se lanzará una excepción.

Cookies de terceros

Tenga en cuenta que la política general de cookies de terceros se aplica a las cookies configuradas en las respuestas de CORS. En el ejemplo anterior, la página se está foo.examplecargando, pero se bar.otherenvía la cookie de la línea 20. Si el usuario ha configurado su navegador para rechazar todas las cookies de terceros, no se guardará.

Campos de encabezado de respuesta HTTP

Esta sección enumera los campos del encabezado de respuesta definidos por la especificación. En la sección anterior, hemos visto cómo funcionan estos campos de encabezado en escenarios prácticos.

Access-Control-Allow-Origin

El encabezado de respuesta puede llevar un campo Access-Control-Allow-Origin, cuya sintaxis es la siguiente:

Access-Control-Allow-Origin: <origin> | *

Entre ellos, el valor del parámetro de origen especifica el URI del dominio externo al que se le permite acceder al recurso. Para las solicitudes que no necesitan llevar credenciales de identidad, el servidor puede especificar el valor de este campo como un comodín, lo que indica que se permiten solicitudes de todos los dominios.

Por ejemplo, el siguiente valor de campo permitirá solicitudes desde http://mozilla.com:

Access-Control-Allow-Origin: http://mozilla.com

Si el servidor especifica un nombre de dominio específico distinto de "*", entonces el valor del campo Variar en el encabezado de respuesta debe contener Origen. Esto le indicará al cliente que el servidor devuelve contenido diferente para diferentes sitios de origen.

Access-Control-Expose-Headers

Nota del traductor: durante el acceso entre orígenes, el método getResponseHeader() del objeto XMLHttpRequest solo puede obtener algunos de los encabezados de respuesta más básicos: Cache-Control, Content-Language, Content-Type, Expires, Last-Modified y Pragma. Si desea acceder a otros encabezados, el servidor debe configurar este encabezado de respuesta.

El encabezado Access-Control-Expose-Headers permite al servidor incluir en la lista blanca los encabezados a los que el navegador puede acceder, por ejemplo:

Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header

De esta manera, el navegador puede acceder a los encabezados de respuesta X-My-Custom-Header y X-Another-Custom-Header a través de getResponseHeader.

Control-de-acceso-edad-máxima

El encabezado Access-Control-Max-Age especifica durante cuánto tiempo se pueden almacenar en caché los resultados de la solicitud de verificación previa. Consulte el ejemplo de verificación previa mencionado anteriormente en este artículo.

Access-Control-Max-Age: <delta-seconds>

El parámetro delta-segundos indica cuántos segundos es válido el resultado de la solicitud de verificación previa.

Access-Control-Allow-Credentials

El encabezado Access-Control-Allow-Credentials especifica si el navegador puede leer el contenido de la respuesta cuando las credenciales del navegador están configuradas como verdaderas. Cuando se utiliza en la respuesta a una solicitud de verificación previa, especifica si la solicitud real puede utilizar credenciales. Tenga en cuenta: las solicitudes GET simples no se someten a verificación previa; si la respuesta a dicha solicitud no contiene este campo, la respuesta se ignorará y el navegador no devolverá el contenido correspondiente a la página.

Access-Control-Allow-Credentials: true

Las solicitudes acompañadas de credenciales se han analizado anteriormente.

Access-Control-Allow-Methods

El campo de encabezado Access-Control-Allow-Methods se utiliza en respuestas a solicitudes de verificación previa. Especifica los métodos HTTP permitidos para la solicitud real.

Access-Control-Allow-Methods: <method>[, <method>]*

Consulte aquí para ver ejemplos relevantes.

Access-Control-Allow-Headers

El campo de encabezado Access-Control-Allow-Headers se utiliza en respuestas a solicitudes de verificación previa. Especifica los campos de encabezado que se permiten incluir en la solicitud real.

Access-Control-Allow-Headers: <field-name>[, <field-name>]*

Proceso de verificación previa

Cuando la solicitud de verificación previa llega al servidor, el servidor en realidad no ejecutará la lógica de la solicitud, solo devolverá algunos encabezados HTTP en la solicitud para indicarle al cliente si debe enviar una solicitud real.

Si el servidor le dice al cliente que se permite enviar la solicitud, entonces se enviará la solicitud real.

Por ejemplo: envié una solicitud para el nombre de dominio conardli.top bajo el origen a.com.

Luego, el navegador primero enviará una verificación previa a conardli.top. La solicitud de verificación previa en realidad no ejecutará la solicitud para este nombre de dominio, pero devolverá algunos encabezados CORS, como Access-Control-Allow-Origin: a.com

En este momento, el navegador descubre que la solicitud de conardli.top puede enviarse desde a.com y luego se emite la solicitud. En este momento, el servidor realmente ejecutará la lógica de la interfaz de solicitud.

Entonces, ¿se realizarán comprobaciones previas en todas las solicitudes? Por supuesto que no.
Solicitudes simples y solicitudes complejas

Aunque la solicitud de verificación previa en realidad no ejecuta la lógica en el servidor, sigue siendo una solicitud. Teniendo en cuenta la sobrecarga del servidor, no todas las solicitudes enviarán una verificación previa.

Una vez que el navegador determina que la solicitud es una solicitud simple, no enviará la verificación previa.

Para determinar si una solicitud es una solicitud simple, el navegador debe cumplir las cuatro condiciones siguientes:

Utilice uno de los siguientes métodos:
OBTENER
PUBLICACIÓN
PRINCIPAL

Solo se utilizan los siguientes encabezados seguros, no se permite configurar artificialmente otros encabezados
texto/plain
multipart/form-data
application/x-www-form-urlencoded
Aceptar
Aceptar-Idioma
Contenido-Idioma

El valor de Content-Type está limitado a uno de los tres siguientes:

  1. No hay detectores de eventos registrados para ningún objeto XMLHttpRequest en la solicitud; se puede acceder a los objetos XMLHttpRequest mediante la propiedad XMLHttpRequest.upload.
  2. No se utilizó ningún objeto ReadableStream en la solicitud.

Por lo tanto, si envía una solicitud simple, independientemente de si está sujeta a restricciones entre dominios, siempre que se envíe, se ejecutará en el lado del servidor y el navegador simplemente ocultará el valor de retorno.

Resumir

Finalmente, resumamos los puntos clave:

  1. Solicitud simple: no importa si es entre dominios o no, siempre que se envíe, definitivamente llegará al servidor y se ejecutará, y el navegador solo ocultará el valor de retorno.
  2. Solicitudes complejas: verificación previa primero. La verificación previa en realidad no ejecutará la lógica de negocios. La solicitud real se enviará y ejecutará en el servidor solo después de que pase la verificación previa.

Supongo que te gusta

Origin blog.csdn.net/weixin_43233219/article/details/130081051
Recomendado
Clasificación