GWTTestCase - HTMLUnit - 不允许 "Access-Control-Allow-Origin"

GWTTestCase - HTMLUnit - No permitted "Access-Control-Allow-Origin"

当运行 GWTTestCase 使用 GWT(使用 Restlet-GWT)调用外部 Restful 服务时,应用会抛出以下错误。

错误:

Jan 05, 2015 1:24:41 PM com.gargoylesoftware.htmlunit.javascript.background.JavaScriptJobManagerImpl runSingleJob
SEVERE: Job run failed with unexpected RuntimeException: Wrapped java.lang.RuntimeException: No permitted "Access-Control-Allow-Origin" header.
net.sourceforge.htmlunit.corejs.javascript.WrappedException: Wrapped java.lang.RuntimeException: No permitted "Access-Control-Allow-Origin" header.
    at net.sourceforge.htmlunit.corejs.javascript.Context.throwAsScriptRuntimeEx(Context.java:1889)
    at com.gargoylesoftware.htmlunit.javascript.host.xml.XMLHttpRequest.doSend(XMLHttpRequest.java:681)
    at com.gargoylesoftware.htmlunit.javascript.host.xml.XMLHttpRequest.access[=11=]0(XMLHttpRequest.java:94)
    at com.gargoylesoftware.htmlunit.javascript.host.xml.XMLHttpRequest.run(XMLHttpRequest.java:603)
    at net.sourceforge.htmlunit.corejs.javascript.Context.call(Context.java:602)
    at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.call(ContextFactory.java:507)
    at com.gargoylesoftware.htmlunit.javascript.background.JavascriptXMLHttpRequestJob.run(JavascriptXMLHttpRequestJob.java:36)
    at com.gargoylesoftware.htmlunit.javascript.background.JavaScriptJobManagerImpl.runSingleJob(JavaScriptJobManagerImpl.java:328)
    at com.gargoylesoftware.htmlunit.javascript.background.DefaultJavaScriptExecutor.run(DefaultJavaScriptExecutor.java:162)
    at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.RuntimeException: No permitted "Access-Control-Allow-Origin" header.
    ... 9 more

根据我的研究,这似乎是 HTMLUnit 不允许访问跨域的问题,是否有解决此问题的方法?

您可以将 CORS 支持添加到您的应用程序中。

在 Restlet 框架的 2.3 版本中提供了支持(参见 http://restlet.com/technical-resources/restlet-framework/guide/2.3/introduction/whats-new/2.3)。 如果您使用的是 2.2 版本,并且由于我们不会将此功能添加到 2.2,您可以在自己的代码中手动添加所需的 类(参见 https://github.com/restlet/restlet-framework-java/blob/2.3/modules/org.restlet/src/org/restlet/service/CorsService.java, https://github.com/restlet/restlet-framework-java/blob/2.3/modules/org.restlet/src/org/restlet/engine/application/CorsFilter.java, and https://github.com/restlet/restlet-framework-java/blob/2.3/modules/org.restlet/src/org/restlet/engine/application/CorsResponseHelper.java)。

我被这个完全相同的错误响应难住了,但我无法将 Restlet 框架重构到我的客户端和服务器代码库中。

一些处理问题诊断的技巧。

  1. 使用代理或检查开发工具在 OPTIONS 和 GET/POST 对的请求和响应中记录确切的 headers。
  2. OPTIONS 请求 header "Origin" 必须与响应 header "Access-Control-Allow-Origin" 完全匹配。没有通配符。也许写下你的回应只是回应这样的请求:

    response.addHeader("Access-control-allow-origin", request.getHeader("Origin"));

  3. 您的请求 header 名称必须在 OPTIONS "Access-control-request-headers" header 值中完整枚举并匹配 "Access-control-Allow-Headers" 响应 header .

注意:#3 中的不匹配会触发与#2 中的不匹配相同的错误消息。