Estoy tratando de obtener algunos datos de la API REST de HP Alm. Funciona bastante bien con un pequeño script curl: obtengo mis datos.
Ahora hacer eso con JavaScript, fetch y ES6 (más o menos) parece ser un problema mayor. Sigo recibiendo este mensaje de error:
Fetch API no se puede cargar. La respuesta a la solicitud de verificación previa no pasa la verificación de control de acceso: no hay ningún encabezado 'Access-Control-Allow-Origin' en el recurso solicitado. Por lo tanto, no se permite el acceso al origen ' http://127.0.0.1:3000 '. La respuesta tenía el código de estado HTTP 501. Si una respuesta opaca satisface sus necesidades, establezca el modo de la solicitud en 'no-cors' para obtener el recurso con CORS deshabilitado.
Entiendo que esto se debe a que estoy tratando de obtener esos datos desde mi host local y la solución debería usar CORS. Ahora pensé que en realidad hice eso, pero de alguna manera ignora lo que escribo en el encabezado o el problema es otro.
Entonces, ¿hay un problema de implementación? ¿Lo estoy haciendo mal? Lamentablemente, no puedo comprobar los registros del servidor. Estoy realmente un poco atascado aquí.
function performSignIn() { let headers = new Headers(); headers.append('Content-Type', 'application/json'); headers.append('Accept', 'application/json'); headers.append('Access-Control-Allow-Origin', 'http://localhost:3000'); headers.append('Access-Control-Allow-Credentials', 'true'); headers.append('GET', 'POST', 'OPTIONS'); headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password)); fetch(sign_in, { //mode: 'no-cors', credentials: 'include', method: 'POST', headers: headers }) .then(response => response.json()) .then(json => console.log(json)) .catch(error => console.log('Authorization failed : ' + error.message)); }Estoy usando Chrome. También intenté usar ese complemento Chrome CORS, pero luego recibo otro mensaje de error:
El valor del encabezado 'Access-Control-Allow-Origin' en la respuesta no debe ser el comodín '*' cuando el modo de credenciales de la solicitud es 'incluir'. Por lo tanto, no se permite el acceso al origen ' http://127.0.0.1:3000 '. El modo de credenciales de las solicitudes iniciadas por XMLHttpRequest está controlado por el atributo withCredentials.
Este error ocurre cuando la URL del cliente y la URL del servidor no coinciden, incluido el número de puerto. En este caso, debe habilitar su servicio para CORS, que es el intercambio de recursos de origen cruzado.
Si está alojando un servicio Spring REST, puede encontrarlo en la publicación de blog Compatibilidad con CORS en Spring Framework .
Si está alojando un servicio utilizando un servidor Node.js, entonces
npm install cors --save const cors=require("cors"); const corsOptions ={ origin:'*', credentials:true, //access-control-allow-credentials:true optionSuccessStatus:200, } app.use(cors(corsOptions)) // Use this after the variable declarationEl problema surgió porque agregó el siguiente código como encabezado de solicitud en su interfaz:
headers.append('Access-Control-Allow-Origin', 'http://localhost:3000'); headers.append('Access-Control-Allow-Credentials', 'true'); Esos encabezados pertenecen a la respuesta , no a la solicitud. Así que elimínelos , incluida la línea:
headers.append('GET', 'POST', 'OPTIONS'); Su solicitud tenía 'Content-Type: application/json' , por lo que activó lo que se denomina verificación previa de CORS. Esto provocó que el navegador enviara la solicitud con el método OPCIONES. Consulte Verificación previa de CORS para obtener información detallada.
Por lo tanto, en su back-end , debe manejar esta solicitud comprobada devolviendo los encabezados de respuesta que incluyen:
Access-Control-Allow-Origin : http://localhost:3000 Access-Control-Allow-Credentials : true Access-Control-Allow-Methods : GET, POST, OPTIONS Access-Control-Allow-Headers : Origin, Content-Type, AcceptPor supuesto, la sintaxis real depende del lenguaje de programación que utilice para su back-end.
En su front-end, debería ser así:
function performSignIn() { let headers = new Headers(); headers.append('Content-Type', 'application/json'); headers.append('Accept', 'application/json'); headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password)); headers.append('Origin','http://localhost:3000'); fetch(sign_in, { mode: 'cors', credentials: 'include', method: 'POST', headers: headers }) .then(response => response.json()) .then(json => console.log(json)) .catch(error => console.log('Authorization failed: ' + error.message)); }