XMLHttpRequest Origin null不允许Access-Control-Allow-Origin for file:/// to file:///(无服务器)

我试图创建一个网站,可以下载并通过启动其索引文件在本地运行。

所有文件都是本地的,没有在线使用资源。

当我尝试使用jQuery的AJAXSLT插件来处理带有XSL模板的XML文件(在子目录中)时,我收到以下错误:

XMLHttpRequest cannot load file:///C:/path/to/XSL%20Website/data/home.xml. Origin null is not allowed by Access-Control-Allow-Origin.

XMLHttpRequest cannot load file:///C:/path/to/XSL%20Website/assets/xsl/main.xsl. Origin null is not allowed by Access-Control-Allow-Origin.

提出请求的索引文件是file:///C:/path/to/XSL%20Website/index.html,而使用的JavaScript文件存储在file:///C:/path/to/XSL%20Website/assets/js/中。

我该如何解决这个问题?

267653 次浏览

从本质上讲,处理这个问题的唯一方法是在本地主机上运行一个web服务器,并从那里为它们提供服务。

浏览器允许ajax请求访问您计算机上的任何文件是不安全的,因此大多数浏览器似乎都将" file://"为了“同源策略"”的目的,请求没有起源;

启动一个web服务器可以像cding到文件所在的目录并运行一样简单:

python -m http.server

[编辑感谢@alextercete,指出它已在Python3中更新]

对于运行本地web服务器不是一个选项的实例,你可以允许Chrome通过浏览器开关访问file://文件。经过一番挖掘,我找到了这个讨论,它在开头的帖子中提到了一个浏览器开关。运行你的Chrome实例:

chrome.exe --allow-file-access-from-files

你当然不希望它一直开着。这似乎仍然是一个悬而未决的问题(截至2011年1月)。

参见:在Chrome中使用本地文件的jQuery getJSON的问题

下面是一个applescript,它将开启——allow-file-access-from-files开关,用于OSX/Chrome开发者:

set chromePath to POSIX path of "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
set switch to " --allow-file-access-from-files"
do shell script (quoted form of chromePath) & switch & " > /dev/null 2>&1 &"

你可以试着把'Access-Control-Allow-Origin':'*'放在response.writeHead(, {[here]})中。

这个解决方案将允许您使用jQuery.getScript()加载本地脚本。这是一个全局设置,但您也可以在每个请求的基础上设置crossDomain选项。

$.ajaxPrefilter( "json script", function( options ) {
options.crossDomain = true;
});

使用javascript FileReader函数来打开本地文件,比如:

<input type="file" name="filename" id="filename">
<script>
$("#filename").change(function (e) {
if (e.target.files != undefined) {
var reader = new FileReader();
reader.onload = function (e) {
// Get all the contents in the file
var data = e.target.result;
// other stuffss................
};
reader.readAsText(e.target.files.item(0));
}
});
</script>

现在单击Choose file按钮并浏览到文件file:///C:/path/to/XSL%20Website/data/home.xml

像这样启动chrome来绕过这个限制:open -a "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --args --allow-file-access-from-files

Josh Lee的评论派生,但我需要指定谷歌Chrome的完整路径,以避免谷歌Chrome从我的Windows分区打开(在Parallels中)。

我解决这个问题的方法是完全不使用XMLHTTPRequest,而是将所需的数据包含在单独的javascript文件中。(在我的情况下,我需要一个二进制SQLite blob使用https://github.com/kripken/sql.js/)

我创建了一个名为base64_data.js的文件(并使用btoa()转换我需要的数据,并将其插入到<div>中,以便复制它)。

var base64_data = "U1FMaXRlIGZvcm1hdCAzAAQA ...<snip lots of data> AhEHwA==";

然后像普通javascript一样将数据包含在HTML中:

<div id="test"></div>


<script src="base64_data.js"></script>
<script>
data = atob(base64_data);
var sqldb = new SQL.Database(data);
// Database test code from the sql.js project
var test = sqldb.exec("SELECT * FROM Genre");
document.getElementById("test").textContent = JSON.stringify(test);
</script>

我想修改它来读取JSON,甚至XML是很简单的;我把这个留给读者做练习吧;)

使用“chrome应用的web服务器”。(不管你知不知道,你的电脑上已经有了。用cortana搜索就可以了!)打开它,点击“选择文件”,选择文件所在的文件夹。不要实际选择文件。选择文件文件夹然后单击“选择文件夹”按钮下的链接。

如果它不带您到文件,然后将文件的名称添加到urs。是这样的:

   https://127.0.0.1:8887/fileName.txt

链接到chrome的web服务器:点击我

如果您只需要在本地访问文件,那么您可以包含文件的确切路径,而不是使用

../images/img.jpg

使用

C:/Users/username/directoryToImg/img.jpg

CORS发生的原因是因为你试图在一个网页中遍历到另一个目录,通过包括直接路径,你不是在改变目录,你是从一个直接位置拉。