2012-04-09 13 views
11

Estoy desarrollando una aplicación en mi PC local. El frontend debería construirse con spinejs y el backend-api con node.js. columna vertebral se ejecuta en el puerto 9294 y Node.js se está ejecutando en el puerto 3000. en la columna vertebral que he añadido a mi modelo lo siguiente:columna vertebral, Node.js (express) y Access-Control-Allow-Origen

@url: "http:localhost:3000/posts" 

y en mi servidor expreso

app.get('/posts', function(req, res){ 
    console.log("giving ALL the posts"); 
    res.header("Access-Control-Allow-Origin", "*") 
    res.json(posts); 
}); 

Pero siempre estoy recibiendo el siguiente erro en cromo:

XMLHttpRequest cannot load http://localhost:3000/posts. Origin http://localhost:9294 is not allowed by Access-Control-Allow-Origin. 

¿Qué debo hacer que puedo acceder a mi api correctamente? Pensé que agregar el encabezado en las respuestas soluciona el problema.

+1

¿Ha inspeccionado la cabecera de respuesta para confirmar que la cabecera se está creando de hecho? Además, jQuery usa el comando HTTP 'OPTIONS' para detectar pre-auth; Asegúrate de que Express también responda a ese Verbo HTTP – tkone

+0

Honestamente, parece que mi solicitud nunca llega a mi servidor node.js. He agregado una declaración de depuración en la aplicación.get() ANTES de que se envíe algo al cliente. Al acceder a mi api directamente sobre la url puedo ver la declaración pero no cuando se accede a través de la columna vertebral – soupdiver

+0

usted debe usar algo como Charles para asegurarse de que esto está sucediendo. Aquí hacemos un montón de cosas del dominio x y es frustrante hasta que veas que el encabezado NO se está configurando. – tkone

Respuesta

16

app.get sólo responderá a las solicitudes GET. Si el navegador realiza una verificación previa con una solicitud OPTIONS, Express enviará un error porque no tiene ningún oyente para esas solicitudes. Trate de añadir este código, además de la suya y ver si funciona:

app.options('/posts', function(req, res){ 
    console.log("writing headers only"); 
    res.header("Access-Control-Allow-Origin", "*"); 
    res.end(''); 
}); 

También tenga en cuenta: si va a enviar las galletas con la solicitud (withcredentials=true), entonces la cabecera Access-Control-Allow-Origin no puede ser *, debe ser la exacta valor en la cabecera Origin que el navegador añade automáticamente a la petición ajax así:

res.header("Access-Control-Allow-Origin", req.headers.origin); 

Esto es por razones de seguridad - si está haciendo algo que requiere cookies, entonces es más probable que usted va a querer en realidad compruebe que el origin es un permitir sitio web ed para evitar CSRF attacks.

+0

gracias amigo! No tenía el método de OPCIONES en la pantalla ... trabajando ahora :) – soupdiver

15

Este middleware permitirá CORS usando Express, la clave es detectar la solicitud de verificación previa OPTIONS y devolver una respuesta para evitar consultas de bases de datos duplicadas o 404. Vea el recurso: http://cuppster.com/2012/04/10/cors-middleware-for-node-js-and-express/

var methodOverride = require('method-override'); 
app.use(methodOverride()); 

// ## CORS middleware 
// see: http://stackoverflow.com/questions/7067966/how-to-allow-cors-in-express-nodejs 
var allowCrossDomain = function(req, res, next) { 
    res.header('Access-Control-Allow-Origin', '*'); 
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE'); 
    res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization'); 

    // intercept OPTIONS method 
    if ('OPTIONS' == req.method) { 
     res.send(200); 
    } 
    else { 
     next(); 
    } 
}; 
app.use(allowCrossDomain); 
+1

¡Finalmente, uno que realmente funciona! ¡Gracias! –

+2

methodOverride ya no se incluye con Express como de la versión 4, por lo que tendrá que incluir "método-override" en su package.json, a continuación, en lugar de 'app.use (express.methodOverride())', 'utilizar methodOverride var \t = require ('method-override'); app.use (methodOverride()); ' –

Cuestiones relacionadas