No' Access-Control-Allow-Origin' ExpressJS到本地服务器

时间:2016-08-25 16:06:22

标签: javascript node.js http express cors

我知道这个主题似乎已经很多次回答了,但我真的不明白。

  • 我有一个本地angular-fullstack应用程序(Express,NodeJs),有他的 服务器A localhost:9000 / )。
  • 我有另一个本地前端应用B (BlurAdmin完成了 generator-gulp-angular)( localhost:3000 /

我的服务器A使用Express和Nodejs自动生成:

  app.use(function (req, res, next) {

    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
    res.setHeader('Access-Control-Allow-Credentials', false);
    next();
});

在我的应用B中,对我的服务器A API的GET请求

$http.get('http://localhost:9000/api/shows')

但是有PUT请求:

$http.put('http://localhost:9000/api/shows/1', object)

我有以下错误:

  

XMLHttpRequest无法加载http://localhost:9000/api/shows/1。没有   '访问控制允许来源'标题出现在请求的上   资源。起源' http://localhost:3000'因此是不允许的   访问。响应的HTTP状态代码为403。

我尝试:

  $http({
    method: "PUT",
    url:'http://localhost:9000/api/shows/1',
    headers: {
      'Content-type': 'application/json'
    },
    data:object
  });

不工作,

我尝试:

res.header('Access-Control-Allow-Origin', '*');

不工作,

我为chrome安装了* ExtensionAllow-Control-Allow-Origin:**并且没有做任何事情(只返回所有代码但只返回错误403(禁止)

我不知道为什么当PUT与GET合作时,这对PUT不起作用。

你有这个问题吗?谢谢!

已更新:1 我的浏览器中的结果: 获取GET

General:
Request URL:http://localhost:9000/api/shows/1
Request Method:OPTIONS
Status Code:200 OK

Request header:
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4,de-DE;q=0.2,de;q=0.2
Access-Control-Request-Headers:content-type
Access-Control-Request-Method:PUT
Connection:keep-alive
Host:localhost:9000
Origin:http://localhost:3000
Referer:http://localhost:3000/

Response header: 
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:X-Requested-With,content-type
Access-Control-Allow-Methods:GET, POST, OPTIONS, PUT, PATCH, DELETE
Access-Control-Allow-Origin:http://localhost:3000
Allow:GET,HEAD,PUT,PATCH,DELETE
Connection:keep-alive
Content-Length:25
Content-Type:text/html; charset=utf-8

对于PUT 请求:

general:
Request URL:http://localhost:9000/api/shows/1
Request Method:PUT
Status Code:403 Forbidden

Response Header:
Connection:keep-alive
Content-Encoding:gzip
Content-Type:application/json; charset=utf-8
Date:Thu, 25 Aug 2016 16:29:44 GMT
set-cookie:connect.sid=s%3AsVwxxbO-rwLH-1IBZdFzZK1xTStkDUdw.xuvw41CVkFCRK2lHNlowAP9vYMUwoRfHtc4KiLqwlJk; Path=/; HttpOnly
set-cookie:XSRF-TOKEN=toaMLibU5zWu2CK19Dfi5W0k4k%2Fz7PYY%2B9Yeo%3D; Path=/
Strict-Transport-Security:max-age=31536000; includeSubDomains; preload

Request header:
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4,de-DE;q=0.2,de;q=0.2
Connection:keep-alive
Content-Length:27
Content-Type:application/json
Host:localhost:9000
Origin:http://localhost:3000
Referer:http://localhost:3000/

Request Payload:
{url_name: "myData"}
url_name
:
"myData"

感谢您的帮助

更新2: https://github.com/troygoode/node-cors-server/blob/master/app.js 以及@Chris Foster的工作 我安装了npm cors --save 在我的app.js中, 我现在有以下代码:

import express from 'express'; 
import cors from 'cors'; 

var app = express()

var corsOptions = {
  origin: 'http://localhost:3000'
}
var issuesoption = {
  origin: true,
  methods: ['PUT'],
  credentials: true,
};


app.use(cors(corsOptions))
app.options('*', cors(issuesoption));
app.put('/api/shows/:id',cors(issuesoption) ,function(req,res){
  res.json({
    data: 'Issue #2 is fixed.'
  });
});

这仍然无效:

$http.put("http://localhost:9000/api/shows/1",object)

但是我没有任何403错误,我现在有,

Request URL:http://localhost:9000/api/shows/1
Request Method:PUT
Status Code:200 OK

没有将数据放入服务器,我在预览中:

{data: "Issue #2 is fixed."}

2 个答案:

答案 0 :(得分:9)

当您提出可以更改内容的请求(POSTPUT等)时,CORS规则要求浏览器在制作之前生成preflight requestOPTIONS)实际的要求。

在Node中,您必须专门处理这些OPTION个请求。您可能只处理PUTapp.put('/etc/etc/')),并且预检请求失败。

您需要add handling进行预检OPTION请求,但最好查看cors包,这样可以更加简单并为您完成:

const express = require('express')
const cors = require('cors')

const app = express()

const corsOptions = {
  origin: 'http://example.com'
}

app.use(cors(corsOptions))

答案 1 :(得分:-2)

未来的人偶然发现了这个问题和这个主题。

如果您对此请求有403状态,请检查您的CSRF令牌。 可能你的节点/快递/后端服务器发送csrf但客户端没有发回它,因为请求是forbiddend(403)。