起源为空不被访问控制允许的来源所接受。

207

我创建了一个小的XSLT文件,用以下代码生成名为weather.xsl的HTML输出:

<!-- DWXMLSource="http://weather.yahooapis.com/forecastrss?w=38325&u=c" -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="yweather"
xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
    <img src="{/*/*/item/yweather:condition/@text}.jpg"/>
</xsl:template>
</xsl:stylesheet>

我想将HTML输出加载到一个HTML文件中的一个div中,我正在尝试使用jQuery执行以下操作:

<div id="result">
<script type="text/javascript">
$('#result').load('weather.xsl');
</script>
</div>

但我遇到了以下错误:Origin null is not allowed by Access-Control-Allow-Origin。

我已经阅读过如何向xslt添加标头的方法,但我不确定该如何做,因此将不胜感激地接受任何帮助。如果无法通过这种方式加载HTML输出,则请提供其他方法。


这是你真正的 load 调用吗?它根本没有路径吗? - T.J. Crowder
为了允许本地页面/HTML文件(Origin: null)从文件系统访问外部资源(不同的来源),这些外部资源应该在响应头中回复 "Access-Control-Allow-Origin": "*" - Maksim Shamihulau
8个回答

251

起源null是本地文件系统,这意味着您通过file:/// URL(例如在本地文件浏览器中双击它)加载load调用的HTML页面。

大多数浏览器对本地文件应用同源策略,甚至阻止从与文档相同目录下加载文件。(过去Firefox允许在同一目录和子目录下加载文件,但现在已经不行了,详见)。

基本上,使用ajax与本地资源无法工作。

如果您只是在本地测试即将部署到Web的内容,而不是使用本地文件,请安装一个简单的Web服务器,并通过http:// URLs 进行测试。这会给您提供更准确的安全情况。您的IDE可能已经内置了某种类型的服务器(直接或通过扩展),让您只需在IDE中点击“运行”,就可以启动服务器并提供文件服务。


1
上传后,我不再收到"Origin null"的错误,但仍然出现"not allowed by Access-Control-Allow-Origin."的错误。 - dudledok
3
如果你正在加载的资源是像你所展示的那样($('#result').load('weather.xsl');),那么不应该发生这种情况,因为请求明显是针对同一源的。如果你尝试从其他地方加载(例如$('#result').load('http://somewhere.else/weather.xsl');),那么你会再次遇到同源策略问题,但是以不同的方式。Ajax请求仅限于同一(请参见答案中的链接),或者如果您使用了启用CORS的浏览器,并且服务器支持CORS,则服务器可以选择是否允许跨域请求。 - T.J. Crowder
3
最简单、最快速的建立一个简单的网络服务器的方法是什么?IIS 是否是最简单的方法呢? - Ciaran Gallagher
14
@CiaranG 我从命令行运行了 python -m SimpleHTTPServer,然后访问了本地主机:8000,对我来说有效。Python 已经预装在 Mac OS X 上了;如果使用其他操作系统,则可能需要安装。 - Dave Liepmann
2
对于那些稍后遇到此问题的人,Firefox在CVE-2019-11730之后不再允许该有限访问。 - WBT
显示剩余2条评论

224

Chrome和Safari限制了使用ajax与本地资源的连接。这就是为什么会出现错误信息:

Origin null is not allowed by Access-Control-Allow-Origin.

解决方案: 使用Firefox或将您的数据上传到临时服务器。如果您仍想使用Chrome,请使用以下选项启动它:

--allow-file-access-from-files

如何将上述参数添加到您的Chrome浏览器:在任务栏上右键单击Chrome图标,右键单击弹出窗口中的Google Chrome并单击属性,在“快捷方式”选项卡下的“目标”文本框中添加上述参数。它将如下所示;

C:\Users\XXX_USER\AppData\Local\Google\Chrome\Application\chrome.exe --allow-file-access-from-files

希望这能帮到你!


21
在 Mac OS X 上,您可以通过打开终端并键入以下命令来使用此选项启动 Chrome:/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --allow-file-access-from-files &请注意,最后的&只是让您可以继续使用终端,不是必需的。注意: 如果关闭终端,Chrome 窗口也将被关闭。 - Bruno Bernardino
3
做了所有事情,关闭和重新打开了,仍然不行(使用Chrome 27.0.1453.116 m在XP上)。 - mplungjan
当我尝试将--allow-file-access-from-files添加到目标路径时,我收到一个“...无效”的消息,这个解决方案仍然有效吗? - alex
在添加这行代码时,Chrome会给出错误提示“……确保路径正确”,并不允许我保存更改。 - Pardeep Jain
这对我不起作用。所以,我找到了这个可行的方法 - chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security - Tushar Walzade
显示剩余2条评论

73

只是想补充一下,“运行Web服务器”的答案似乎很令人畏惧,但如果你的系统上安装了Python(至少默认情况下安装在MacOS和任何Linux分发版上),那么它就像这样简单:

python -m http.server  # with python3
或者
python -m SimpleHTTPServer  # with python2

如果你有一个html文件myfile.html在一个文件夹中,比如说mydir,那么你所需要做的就是:

因此,只需执行以下操作:

cd /path/to/mydir
python -m http.server  # or the python2 alternative above

然后将您的浏览器指向:

http://localhost:8000/myfile.html

完成了!在所有浏览器上都有效,无需禁用Web安全,允许本地文件,甚至重新启动浏览器使用命令行选项。


3
在Windows上,Python 3的等效命令是:python -m http.server [<portNo>]。请注意,这个命令是用来启动一个简单的HTTP服务器,并在指定端口(如果提供)上监听请求。 - Aragorn
1
Python 3: python3 -m http.server - João Nunes
1
在Linux上使用Python 2,选择8080端口(或任何其他您想要的端口):python -m SimpleHTTPServer 8080 - rodrigocfd
虽然这很酷,但可悲的是它并没有解决我的CORS问题。天哪,我真希望我对CORS了解更多。至少有点酷的东西,给你一个赞。 - netskink
需要一个快速的CORS测试机制,这个工作得很好,谢谢。 - Barry McDermid

1

添加一点内容,使用Gokhan的解决方案:

--allow-file-access-from-files

现在,您只需要将上述文本附加到目标文本中,并在其后添加一个空格。 确保在添加上述属性后关闭所有Chrome浏览器实例。 现在通过您添加此属性的图标重新启动Chrome。 它应该适用于所有情况。

该参数已由Ghokan Tank提供,如何始终使用此参数启动浏览器不是问题的一部分。另外,您不能假设每个人都使用Microsoft Windows。 - jnns

1
我希望您能谦虚地补充一下,根据这个SO来源:https://stackoverflow.com/a/14671362/1743693,通过使用以下jQuery指令,这种问题现在已经部分得到解决:
<script> 
    $.support.cors = true;
</script>

我在IE10.0.9200上尝试过,它立即生效了(使用jquery-1.9.0.js)。

在chrome 28.0.1500.95上 - 这个指令不起作用(这在链接上方的评论中david抱怨)

使用--allow-file-access-from-files运行chrome对我没有用(就像Maistora在上面声称的那样)


0
我正在寻找一种方法,从本地HTML文件向服务器发出XHR请求,并找到了使用Chrome和PHP的解决方案(没有Jquery)。
Javascripts:
var x = new XMLHttpRequest(); 
if(x) x.onreadystatechange=function(){ 
    if (x.readyState === 4 && x.status===200){
        console.log(x.responseText); //Success
    }else{ 
        console.log(x); //Failed
    }
};
x.open(GET, 'http://example.com/', true);
x.withCredentials = true;
x.send();

我的Chrome请求头 Origin: null

我的PHP响应头(请注意,'null'是一个字符串)。HTTP_REFERER允许从远程服务器到另一个服务器的跨域。

header('Access-Control-Allow-Origin: '.(trim($_SERVER['HTTP_REFERER'],'/')?:'null'),true);
header('Access-Control-Allow-Credentials:true',true);

我成功连接到了我的服务器。

您可以忽略Credentials头,但如果启用了Apache的AuthType Basic,这对我有效。

我已测试过与Firefox和Opera的兼容性,在许多情况下都有效:

从VM LAN IP(192.168.0.x)返回到VM的WAN(公共)IP:端口
从VM LAN IP返回到远程服务器域名。
从本地.HTML文件返回到VM LAN IP和/或VM WAN IP:端口
从本地.HTML文件返回到远程服务器域名。
等等。


-1
使用Java Spring运行Web服务时,您需要在自动生成的YouAppApplication.java文件(带有main()函数的那个)中,在@SpringBootApplication的上方添加@ServletComponentScan,并创建一个具有以下实现的类:
@WebFilter("/*")
public class AddResponseHeaderFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // ...
    }

    @Override
    public void doFilter(ServletRequest servletRequest,
                         ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
        httpServletResponse.addHeader("Access-Control-Allow-Origin", "null");

        httpServletResponse.addHeader("Access-Control-Allow-Credentials", "true");
         filterChain.doFilter(servletRequest, servletResponse);

    }

    @Override
    public void destroy() {
        // ...
    }
}

请注意,一旦实现了Filter并具有@WebFilter注释,您可以为此类选择不同的名称,也可以提供不同于/*的通配符,以便此过滤器不适用于每个端点。
根据@Louis Loudog Trottier的规定,在创建Ajax请求时需要添加...withCredentials = true;才能使其正常工作。


-1

您可以使用source标签加载本地的Javascript文件(在file:/源页面下方的树形目录中):

<script src="my_data.js"></script>

如果您将输入编码为JavaScript,就像在这种情况下:

mydata.js:

$xsl_text = "<xsl:stylesheet version="1.0" + ....

(这对于JSON来说更容易)然后你就可以把你的“数据”存储在一个Javascript全局变量中,以便随意使用。


这正是OP遇到的问题。你的解决方案不起作用。 - us_david

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接