what react problem herokuapp has example been allow javascript reactjs cors create-react-app fetch-api

javascript - react - Intentando usar fetch and pass en modo: no-cors



react fetch mode no cors (5)

Puedo llegar a este punto final, http://catfacts-api.appspot.com/api/facts?number=99 través de Postman y devuelve JSON

Además, estoy usando create-react-app y me gustaría evitar configurar cualquier configuración de servidor.

En mi código de cliente, estoy tratando de usar fetch para hacer lo mismo, pero aparece el error:

No hay encabezado ''Access-Control-Allow-Origin'' presente en el recurso solicitado. Por lo tanto, el origen '' http: // localhost: 3000 '' no tiene acceso permitido. Si una respuesta opaca satisface sus necesidades, configure el modo de solicitud en ''no-cors'' para recuperar el recurso con CORS deshabilitado.

Así que estoy tratando de pasar un objeto a mi Fetch que deshabilitará CORS, así:

fetch(''http://catfacts-api.appspot.com/api/facts?number=99'', { mode: ''no-cors''}) .then(blob => blob.json()) .then(data => { console.table(data); return data; }) .catch(e => { console.log(e); return e; });

Curiosamente, el error que obtengo es en realidad un error de sintaxis con esta función. No estoy seguro de que mi fetch real esté rota, porque cuando elimino el objeto {mode: ''no-cors''} y le proporciono una URL diferente, funciona bien.

También intenté pasar el objeto { mode: ''opaque''} , pero esto devuelve el error original de arriba.

Creo que todo lo que necesito hacer es deshabilitar CORS. ¿Qué me estoy perdiendo?


La solución simple: agregue lo siguiente a la parte superior del archivo php del que solicita los datos.

header("Access-Control-Allow-Origin: *");


Entonces, si eres como yo y estás desarrollando un sitio web en localhost donde estás tratando de obtener datos de Laravel API y usarlos en tu front-end de Vue, y ves este problema, así es como lo resolví:

  1. En su proyecto Laravel, ejecute el comando php artisan make:middleware Cors . Esto creará la app/Http/Middleware/Cors.php para usted.
  2. Agregue el siguiente código dentro de la función de handles en Cors.php :

    return $next($request) ->header(''Access-Control-Allow-Origin'', ''*'') ->header(''Access-Control-Allow-Methods'', ''GET, POST, PUT, DELETE, OPTIONS'');

  3. En app/Http/kernel.php , agregue la siguiente entrada en la matriz $routeMiddleware :

    ‘cors’ => /App/Http/Middleware/Cors::class

    (Habría otras entradas en la matriz como auth , guest , etc. También asegúrese de hacerlo en app/Http/kernel.php porque también hay otro kernel.php en Laravel)

  4. Agregue este middleware en el registro de ruta para todas las rutas donde desea permitir el acceso, de esta manera:

    Route::group([''middleware'' => ''cors''], function () { Route::get(''getData'', ''v1/MyController@getData''); Route::get(''getData2'', ''v1/MyController@getData2''); });

  5. En el front-end de Vue, asegúrese de llamar a esta API en la función mounted() y no en data() . También asegúrese de usar http:// o https:// con la URL en su llamada fetch() .

Créditos completos al artículo del blog de Pete Houston.


La solución muy fácil (2 minutos para configurar) es usar local-ssl-proxy paquete local-ssl-proxy de npm

El uso es bastante sencillo:
1. Instale el paquete: npm install -g local-ssl-proxy
2. Mientras ejecuta su local-server enmascaré con el local-ssl-proxy --source 9001 --target 9000

PD: Reemplace --target 9000 con el -- "number of your port" y --source 9001 con --source "number of your port +1"


La solución para mí era simplemente hacerlo del lado del servidor

WebClient biblioteca C # WebClient para obtener los datos (en mi caso, eran datos de imágenes) y enviarlos de vuelta al cliente. Probablemente haya algo muy similar en el idioma del lado del servidor elegido.

//Server side, api controller [Route("api/ItemImage/GetItemImageFromURL")] public IActionResult GetItemImageFromURL([FromQuery] string url) { ItemImage image = new ItemImage(); using(WebClient client = new WebClient()){ image.Bytes = client.DownloadData(url); return Ok(image); } }

Puede ajustarlo a lo que sea su propio caso de uso. El punto principal es client.DownloadData() funcionó sin ningún error CORS. Por lo general, los problemas de CORS son solo entre sitios web, por lo tanto, está bien hacer solicitudes ''entre sitios'' desde su servidor.

Entonces, la llamada de recuperación de React es tan simple como:

//React component fetch(`api/ItemImage/GetItemImageFromURL?url=${imageURL}`, { method: ''GET'', }) .then(resp => resp.json() as Promise<ItemImage>) .then(imgResponse => { // Do more stuff.... )}


mode: ''no-cors'' adición mode: ''no-cors'' mágicamente no hará que las cosas funcionen. De hecho, empeora las cosas, porque un efecto que tiene es decirle a los navegadores: "Bloquee el código JavaScript de mi interfaz para que no vea el contenido del cuerpo de respuesta y los encabezados en todas las circunstancias". Por supuesto, eso casi nunca es lo que desea.

Lo que sucede con las solicitudes de origen cruzado de JavaScript frontend es que los navegadores de forma predeterminada impiden que el código frontend acceda a los recursos de origen cruzado. Si un sitio envía Access-Control-Allow-Origin en sus respuestas, los navegadores relajarán ese bloqueo y permitirán que su código acceda a la respuesta.

Pero si un sitio no envía un encabezado Access-Control-Allow-Origin en sus respuestas, no hay forma de que su código de interfaz pueda acceder directamente a las respuestas desde ese sitio. En particular, no puede solucionarlo especificando el mode: ''no-cors'' (de hecho, eso asegurará que su código frontend no pueda acceder al contenido de la respuesta).

Sin embargo, una cosa que funcionará es si envía su solicitud a través de un proxy CORS , como este:

var proxyUrl = ''https://cors-anywhere.herokuapp.com/'', targetUrl = ''http://catfacts-api.appspot.com/api/facts?number=99'' fetch(proxyUrl + targetUrl) .then(blob => blob.json()) .then(data => { console.table(data); document.querySelector("pre").innerHTML = JSON.stringify(data, null, 2); return data; }) .catch(e => { console.log(e); return e; });

<pre></pre>

Nota: si cuando intenta utilizar https://cors-anywhere.herokuapp.com, encuentra que está inactivo , también puede implementar fácilmente su propio proxy en Heroku en literalmente solo 2-3 minutos, con 5 comandos:

git clone https://github.com/Rob--W/cors-anywhere.git cd cors-anywhere/ npm install heroku create git push heroku master

Después de ejecutar esos comandos, terminará con su propio servidor CORS Anywhere ejecutándose en, por ejemplo, https://cryptic-headland-94862.herokuapp.com/ . Entonces, en lugar de prefijar su URL de solicitud con https://cors-anywhere.herokuapp.com , prefije en su lugar con la URL de su propia instancia; por ejemplo, https://cryptic-headland-94862.herokuapp.com/https://example.com .

Puedo llegar a este punto final, http://catfacts-api.appspot.com/api/facts?number=99 través de Postman

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS explica por qué es que, aunque puede acceder a la respuesta con Postman, los navegadores no le permitirán acceder a la respuesta de origen cruzado desde la interfaz Código JavaScript que se ejecuta en una aplicación web a menos que la respuesta incluya un encabezado de respuesta Access-Control-Allow-Origin .

http://catfacts-api.appspot.com/api/facts?number=99 no tiene encabezado de respuesta Access-Control-Allow-Origin , por lo que no hay forma de que el código de la interfaz pueda acceder al origen cruzado de la respuesta.

Su navegador puede obtener una buena respuesta y puede verla en Postman e incluso en las herramientas del navegador, pero eso no significa que los navegadores lo expongan a su código. No lo harán, porque no tiene encabezado de respuesta Access-Control-Allow-Origin . Por lo tanto, debe usar un proxy para obtenerlo.

El proxy realiza la solicitud a ese sitio, obtiene la respuesta, agrega el encabezado de respuesta Access-Control-Allow-Origin y cualquier otro encabezado CORS necesario, luego lo devuelve a su código de solicitud. Y esa respuesta con el encabezado Access-Control-Allow-Origin agregado es lo que ve el navegador, por lo que el navegador permite que su código frontend realmente acceda a la respuesta.

Así que estoy tratando de pasar un objeto a mi Fetch que deshabilitará CORS

No quieres hacer eso. Para ser claros, cuando dice que desea "deshabilitar CORS", parece que realmente quiere decir que desea deshabilitar la política del mismo origen . CORS en sí mismo es en realidad una forma de hacerlo: CORS es una forma de aflojar la política del mismo origen, no una forma de restringirla.

Pero de todos modos, es cierto que puede, solo en su entorno local, hacer cosas como dar banderas de tiempo de ejecución de su navegador para deshabilitar la seguridad y ejecutar de forma insegura, o puede instalar una extensión de navegador localmente para evitar la política del mismo origen, pero todo eso hace es cambiar la situación solo para usted localmente.

No importa lo que cambie localmente, cualquier otra persona que intente usar su aplicación todavía se encontrará con la política del mismo origen, y no hay forma de que pueda deshabilitarla para otros usuarios de su aplicación.

Lo más probable es que nunca quieras usar el mode: ''no-cors'' en la práctica, excepto en algunos casos limitados , e incluso entonces solo si sabes exactamente lo que estás haciendo y cuáles son los efectos. Eso se debe a que el mode: ''no-cors'' configuración mode: ''no-cors'' realmente le dice al navegador es: "Bloquear mi código JavaScript frontend para que no busque en el contenido del cuerpo de respuesta y los encabezados en todas las circunstancias". .

En cuanto a los casos en que desea considerar el uso del mode: ''no-cors'' , vea la respuesta en ¿Qué limitaciones se aplican a las respuestas opacas? para los detalles La esencia de esto es que los casos son:

  • En el caso limitado cuando está usando JavaScript para hacer un recurso de otro origen, el contenido de un <script> , <link rel=stylesheet> , <img> , <video> , <audio> , <object> , <embed> , o elemento <iframe> (que funciona porque la inclusión de recursos de origen cruzado está permitida para ellos), pero por alguna razón no desea o no puede hacerlo simplemente haciendo que el marcado del documento use el recurso URL como el atributo href o src para el elemento.

  • Cuando lo único que desea hacer con un recurso es almacenarlo en caché. Como se mencionó en la respuesta en ¿Qué limitaciones se aplican a las respuestas opacas? , en la práctica, el escenario que se aplica es cuando usa Service Workers, en cuyo caso la API relevante es la API de almacenamiento en caché .

Pero incluso en esos casos limitados, hay algunas trampas importantes a tener en cuenta; vea la respuesta en ¿Qué limitaciones se aplican a las respuestas opacas? para los detalles

También he tratado de pasar el objeto { mode: ''opaque''}

No hay mode: ''opaque'' solicitud mode: ''opaque'' : en su lugar, opaque es solo una propiedad de la respuesta , y los navegadores configuran esa propiedad opaca en las respuestas de las solicitudes enviadas con el modo no-cors .

Pero, incidentalmente, la palabra opaco es una señal bastante explícita sobre la naturaleza de la respuesta con la que termina: "opaco" significa que no puede verla.