我在过去48小时内学到了很多关于跨域政策的知识,但显然还不够。
继续this问题。我的HTML5游戏支持Facebook登录。我试图下载人物朋友的个人资料照片。在我的游戏的HTML5版本中,我在Chrome中收到以下错误。
detailMessage:" com.google.gwt.core.client.JavaScriptException: (SecurityError)↵stack:错误:无法执行' texImage2D'上 ' WebGLRenderingContext':可能无法加载受污染的画布。
据我了解,出现此错误是因为我尝试从其他域加载图片,但这可以使用 Access-Control-Allow-Origin 标头解决,详见this问题。
我尝试下载的网址是
https://graph.facebook.com/1387819034852828/picture?width=150&height=150
查看Chrome中的网络标签我可以看到它具有所需的 access-control-allow-origin 标头,并以302重定向到新网址进行响应。该URL有所不同,我想这取决于负载平衡,但这是一个示例URL。
此网址还包含 access-control-allow-origin 标头。所以我不明白为什么会失败。
作为Facebook,以及成千上万的应用,游戏和网站显示用户个人资料图片的事实,我认为这是可能的。我知道我可以通过自己的服务器反弹,但我不确定为什么我应该这样做。
我最终使用以下代码在libgdx中进行跨域映像加载(这非常hacky,我确信可以改进)。我还没有设法使用AssetDownloader。我希望最终能够解决这个问题。
public void downloadPixmap(final String url, final DownloadPixmapResponse response) {
final RootPanel root = RootPanel.get("embed-html");
final Image img = new Image(url);
img.getElement().setAttribute("crossOrigin", "anonymous");
img.addLoadHandler(new LoadHandler() {
@Override
public void onLoad(LoadEvent event) {
HtmlLauncher.application.getPreloader().images.put(url, ImageElement.as(img.getElement()));
response.downloadComplete(new Pixmap(Gdx.files.internal(url)));
root.remove(img);
}
});
root.add(img);
}
interface DownloadPixmapResponse {
void downloadComplete(Pixmap pixmap);
void downloadFailed(Throwable e);
}
答案 0 :(得分:15)
您在申请之前是否在img上设置了crossOrigin
属性?
var img = new Image();
img.crossOrigin = "anonymous";
img.src = "https://graph.facebook.com/1387819034852828/picture?width=150&height=150";
当问到这个问题时,它正在为我工作。遗憾的是,上面的网址不再指向任何内容,因此我在下面的示例中对其进行了更改
var img = new Image();
img.crossOrigin = "anonymous"; // COMMENT OUT TO SEE IT FAIL
img.onload = uploadTex;
img.src = "https://i.imgur.com/ZKMnXce.png";
function uploadTex() {
var gl = document.createElement("canvas").getContext("webgl");
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
try {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
log("DONE: ", gl.getError());
} catch (e) {
log("FAILED to use image because of security:", e);
}
}
function log() {
var div = document.createElement("div");
div.innerHTML = Array.prototype.join.call(arguments, " ");
document.body.appendChild(div);
}

<body></body>
&#13;
如何检查您是否收到标题
打开您的devtools,选择网络选项卡,重新加载页面,选择有问题的图像,查看REQUEST标头和RESPONSE标头。
请求应显示您的浏览器发送了Origin:
标题
回复应显示收到
Access-Control-Allow-Methods: GET, OPTIONS, ...
Access-Control-Allow-Origin: *
注意,响应和请求必须显示上面的条目。如果请求丢失Origin:
,那么您没有设置img.crossOrigin
,即使响应显示确定,浏览器也不会让您使用该图片。
如果您的请求具有Origin:
标头,并且响应没有其他标头,则该服务器未授予使用该图像显示它的权限。换句话说,它可以在图像标签中工作,你可以将它绘制到画布上,但你不能在WebGL中使用它,你绘制的任何2d画布都会被污染,toDataURL
和{{1将停止工作
答案 1 :(得分:0)
您可以对纹理进行base64编码。
答案 2 :(得分:0)
这是您在本地开发时遇到的典型跨域问题。
我使用python的简单服务器作为快速解决方案。
导航到终端中的目录,然后键入:
$ python -m SimpleHTTPServer
你会得到
Serving HTTP on 0.0.0.0 port 8000 ...
所以转到0.0.0.0:8000/并且您应该看到问题已解决。