javascript - falta - Access-Control-Allow-Origin y Angular.js $ http
enable cors angular 6 (7)
Cada vez que hago una aplicación web y me aparece un problema CORS, empiezo a preparar café. Después de joderlo por un tiempo, logro hacerlo funcionar, pero esta vez no es así y necesito ayuda.
Aquí está el código del lado del cliente:
$http({method: ''GET'', url: ''http://localhost:3000/api/symbol/junk'',
headers:{
''Access-Control-Allow-Origin'': ''*'',
''Access-Control-Allow-Methods'': ''GET, POST, PUT, DELETE, OPTIONS'',
''Access-Control-Allow-Headers'': ''Content-Type, X-Requested-With'',
''X-Random-Shit'':''123123123''
}})
.success(function(d){ console.log( "yay" ); })
.error(function(d){ console.log( "nope" ); });
El lado del servidor es un node.js regular con una aplicación express. Tengo una extensión llamada cors y está siendo utilizada con express de esta manera:
var app = express();
app.configure(function(){
app.use(express.bodyParser());
app.use(app.router);
app.use(cors({origin:"*"}));
});
app.listen(3000);
app.get(''/'', function(req, res){
res.end("ok");
});
Si lo hago
curl -v -H "Origin: https://github.com" http://localhost:3000/
Vuelve con:
* Adding handle: conn: 0x7ff991800000
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7ff991800000) send_pipe: 1, recv_pipe: 0
* About to connect() to localhost port 3000 (#0)
* Trying ::1...
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.30.0
> Host: localhost:3000
> Accept: */*
> Origin: https://github.com
>
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Date: Tue, 24 Dec 2013 03:23:40 GMT
< Connection: keep-alive
< Transfer-Encoding: chunked
<
* Connection #0 to host localhost left intact
ok
Si ejecuto el código del lado del cliente, esto representa un error:
OPTIONS http://localhost:3000/api/symbol/junk No ''Access-Control-Allow-Origin'' header is present on the requested resource. Origin ''http://localhost:8000'' is therefore not allowed access. angular.js:7889
XMLHttpRequest cannot load http://localhost:3000/api/symbol/junk. No ''Access-Control-Allow-Origin'' header is present on the requested resource. Origin ''http://localhost:8000'' is therefore not allowed access. localhost/:1
nope
Comprobando los encabezados de Chromes:
Request URL:http://localhost:3000/api/symbol/junk
Request Method:OPTIONS
Status Code:200 OK
Request Headersview source
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8,es;q=0.6,pt;q=0.4
Access-Control-Request-Headers:access-control-allow-origin, accept, access-control-allow-methods, access-control-allow-headers, x-random-shit
Access-Control-Request-Method:GET
Cache-Control:max-age=0
Connection:keep-alive
Host:localhost:3000
Origin:http://localhost:8000
Referer:http://localhost:8000/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
Response Headersview source
Allow:GET
Connection:keep-alive
Content-Length:3
Content-Type:text/html; charset=utf-8
Date:Tue, 24 Dec 2013 03:27:45 GMT
X-Powered-By:Express
Verificando los encabezados de solicitud veo que mi cadena de prueba X-Random-Shit está presente en "Access-Control-Request-Headers" pero su valor no está allí. Además, en mi cabeza esperaba ver una línea para cada uno de los encabezados que estoy configurando, no una gota.
ACTUALIZACIONES ---
Cambié mi frontend a jQuery en lugar de Angular e hice mi backend así:
var app = express();
app.configure(function(){
app.use(express.bodyParser());
app.use(app.router);
});
app.all(''*'', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header(''Access-Control-Allow-Methods'', ''OPTIONS,GET,POST,PUT,DELETE'');
res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");
if (''OPTIONS'' == req.method){
return res.send(200);
}
next();
});
app.get(''/'', function(req, res){
res.end("ok");
});
Ahora funciona con GET pero no con nada más (PUT, POST ..).
Veré si alguno de ustedes encuentra una solución. Mientras tanto, tirando el concepto RESTful por la ventana y haciendo todo con GET.
¡Escribir este middleware podría ayudar!
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
para más detalles, visite http://enable-cors.org/server_expressjs.html
@Swapnil Niwane
Pude resolver este problema llamando a una solicitud de Ajax y formateando la información a ''jsonp''.
$.ajax({
method: ''GET'',
url: url,
defaultHeaders: {
''Content-Type'': ''application/json'',
"Access-Control-Allow-Origin": "*",
''Accept'': ''application/json''
},
dataType: ''jsonp'',
success: function (response) {
console.log("success ");
console.log(response);
},
error: function (xhr) {
console.log("error ");
console.log(xhr);
}
});
Añadiendo a continuación a server.js resolvió el mío
server.post(''/your-rest-endpt/*'', function(req,res){
console.log('''');
console.log(''req.url: ''+req.url);
console.log(''req.headers: '');
console.dir(req.headers);
console.log(''req.body: '');
console.dir(req.body);
var options = {
host: ''restAPI-IP'' + '':'' + ''8080''
, protocol: ''http''
, pathname: ''your-rest-endpt/''
};
console.log(''options: '');
console.dir(options);
var reqUrl = url.format(options);
console.log("Forward URL: "+reqUrl);
var parsedUrl = url.parse(req.url, true);
console.log(''parsedUrl: '');
console.dir(parsedUrl);
var queryParams = parsedUrl.query;
var path = parsedUrl.path;
var substr = path.substring(path.lastIndexOf("rest/"));
console.log(''substr: '');
console.dir(substr);
reqUrl += substr;
console.log("Final Forward URL: "+reqUrl);
var newHeaders = {
};
//Deep-copy it, clone it, but not point to me in shallow way...
for (var headerKey in req.headers) {
newHeaders[headerKey] = req.headers[headerKey];
};
var newBody = (req.body == null || req.body == undefined ? {} : req.body);
if (newHeaders[''Content-type''] == null
|| newHeaders[''Content-type''] == undefined) {
newHeaders[''Content-type''] = ''application/json'';
newBody = JSON.stringify(newBody);
}
var requestOptions = {
headers: {
''Content-type'': ''application/json''
}
,body: newBody
,method: ''POST''
};
console.log("server.js : routes to URL : "+ reqUrl);
request(reqUrl, requestOptions, function(error, response, body){
if(error) {
console.log(''The error from Tomcat is --> '' + error.toString());
console.dir(error);
//return false;
}
if (response.statusCode != null
&& response.statusCode != undefined
&& response.headers != null
&& response.headers != undefined) {
res.writeHead(response.statusCode, response.headers);
} else {
//404 Not Found
res.writeHead(404);
}
if (body != null
&& body != undefined) {
res.write(body);
}
res.end();
});
});
He encontrado una forma de utilizar el método JSONP
en $http
directamente y con soporte de params
en el objeto config:
params = {
''a'': b,
''callback'': ''JSON_CALLBACK''
};
$http({
url: url,
method: ''JSONP'',
params: params
})
Prueba con esto:
$.ajax({
type: ''POST'',
url: URL,
defaultHeaders: {
''Content-Type'': ''application/json'',
"Access-Control-Allow-Origin": "*",
''Accept'': ''application/json''
},
data: obj,
dataType: ''json'',
success: function (response) {
// BindTableData();
console.log("success ");
alert(response);
},
error: function (xhr) {
console.log("error ");
console.log(xhr);
}
});
Soy nuevo en AngularJS y me encontré con este problema CORS, ¡casi me vuelvo loco! Afortunadamente, encontré una forma de arreglar esto. Entonces aquí va ...
Mi problema era que cuando uso el recurso AngularJS $ en el envío de solicitudes de API recibo este mensaje de error. XMLHttpRequest cannot load http://website.com. No ''Access-Control-Allow-Origin'' header is present on the requested resource. Origin ''http://localhost'' is therefore not allowed access.
XMLHttpRequest cannot load http://website.com. No ''Access-Control-Allow-Origin'' header is present on the requested resource. Origin ''http://localhost'' is therefore not allowed access.
Sí, ya agregué callback = "JSON_CALLBACK" y no funcionó.
Lo que hice para solucionar el problema, en lugar de utilizar el método GET o recurrir a $ http.get, he usado JSONP. Simplemente reemplace el método GET con JSONP y cambie también el formato de respuesta de la API a JSONP.
myApp.factory(''myFactory'', [''$resource'', function($resource) {
return $resource( ''http://website.com/api/:apiMethod'',
{ callback: "JSON_CALLBACK", format:''jsonp'' },
{
method1: {
method: ''JSONP'',
params: {
apiMethod: ''hello world''
}
},
method2: {
method: ''JSONP'',
params: {
apiMethod: ''hey ho!''
}
}
} );
}]);
Espero que alguien encuentre esto útil. :)
Tuve éxito con expresar y editar res.header
. El mío coincide con el tuyo muy de cerca, pero tengo un Allow-Headers
diferentes Allow-Headers
como se indica a continuación:
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
También estoy usando Angular y Node / Express, pero no tengo los encabezados indicados en el código Angular, solo el nodo / express