浏览器没有为跨源请求设置原始标头?

时间:2018-02-12 19:18:14

标签: cors cross-domain same-origin-policy allow-same-origin

我有一个简单的index.html文件。此html从localhost:3000

加载
<body>
    <h1>Some app</h1>
    <script src="http://localhost:3005/script.js"></script>
</body>

script.js设置为从其他来源加载:localhost:3005

根据我的理解,浏览器应截取请求并向其添加原始标题,并向localhost:3005服务器发出预检请求,以检查允许localhost:3000

但我没有origin。浏览器似乎没有添加原始标头。 这是负责提供script.js文件(localhost:3005)的服务器。我正在使用cors module

const app = express()

const whitelist = ["http://localhost:3001"]
const corsOptions = {
    origin: function(origin, callback) {
        console.log("origin is: ", origin);      //undefined -- why is undefined??

        if (whitelist.indexOf(origin) !== -1) {
            callback(null, true)
        }
        else {
            callback(new Error('Not allowed by CORS'))
        }
    }
}

app.use(cors(corsOptions), express.static(__dirname))
app.listen(3005, () => {
    console.log("server listening on port 3005")
})

我的实际目标是白名单 localhost:3000请求我script.js

我把localhost:3001只是为了测试我是否真的得到了一个cors错误 - 应该是这样。

但我甚至没有得到起源 - 导致这种情况的原因是什么? 我在Firefox和Chrome中都有相同的行为。我误解了这个洞的过程吗?谢谢:))

编辑:也许看到请求有帮助

browser doesn't attach the origin header

2 个答案:

答案 0 :(得分:2)

我认为你可能误解了CORS的目的。它使服务器能够选择加入某些类型的请求,否则这些请求将在浏览器的同源策略下被禁止。它没有提供一种机制来禁止以前允许的请求。

在同源策略下始终允许从src <script>标签中的外源创建脚本,因此CORS根本不适用。这就是请求中没有标题的原因。

  

我的实际目标是仅列出localhost:3000的白名单,要求我script.js

你不能使用CORS。事实上,你根本不可能做到这一点。我会后退一步,问你为什么要那样做。如果您正在尝试保护私人数据,那么可能需要某种身份验证机制(令牌,cookie,等等)。

答案 1 :(得分:1)

对于可能遇到此问题的其他人,这是凯文·克里斯托弗·亨利(Kevin Christopher Henry)上面接受的答案的实际证明。

下面的第一个代码段从域www.w3schools.com请求一个脚本(带有src URL的.js文件)(并在请求成功后也自动执行),但这就是在这里不重要)。这里要注意两件事:

  1. 此脚本请求是从不同于其来源的域(www.w3schools.com)发出的。
  2. 这成功运行。

$.ajax({
  url: 'https://www.w3schools.com/lib/w3codecolor.js',
  dataType: "script",
  success: function(data, status) {
    console.log('Result:', status)
  },
  error: function(err, status) {
    console.log('Error:', error);
  },
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

下面的第二段代码使用XHR请求从域https://www.w3schools.com/bootstrap到特定路由/页面的URL(www.w3schools.com)。这是向API端点发出请求时将使用的方式。 这是CORS的管辖权。这里需要注意两点:

  1. 此请求是向与其发出请求的域不同的域(www.w3schools.com)发出的。
  2. 之所以失败,是因为现代浏览器默认情况下会限制跨域HTTP请求(see more)。现在,解决此问题的唯一方法是在www.w3schools.com域上配置CORS以接受来自其自身域外的XHR请求。

$.ajax({
  url: 'https://www.w3schools.com/bootstrap',
  success: function(data, status) {
    console.log('Result:', status)
  },
  error: function(err, status) {
    console.log('Error:', err);
  },
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

这里的错误是模棱两可的。要查看实际的CORS错误,请打开Web Developers Console,然后应该会看到

"Access to XMLHttpRequest at 'https://www.w3schools.com/bootstrap' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource."

现在错误之所以说“ from origin'null”,是因为这些代码段可能是在沙盒环境中运行的,甚至没有将请求标头Origin设置为“ https://stackoverflow.com

但是,如果Origin实际上设置为“ https://stackoverflow.com”,则结果将相同。随时将上面的脚本复制粘贴到Web Developer Console中,然后尝试一下。