Skip to content

Safari's bizarre caching of CORS resources breaks preloading #1355

@toolness

Description

@toolness

The following "game" just presents a one-eyed fly blinking, with a "blop" sound playing once per second. The spritesheet and sound are retrieved from a separate domain with CORS enabled.

<!DOCTYPE html>
<meta charset="utf-8">
<title>Safari CORS Lameness Example</title>
<div id="phaser-holder"></div>
<script src="//cdnjs.cloudflare.com/ajax/libs/phaser/2.1.3/phaser.min.js"></script>
<script>
var game = new Phaser.Game(288, 216, Phaser.CANVAS, 'phaser-holder', {
  preload: function() {
    game.load.crossOrigin = "anonymous";
    game.load.spritesheet("fly", "https://s3.amazonaws.com/safari-cors-lameness/fly-flying.png", 80, 92);
    game.load.audio("blop", "https://s3.amazonaws.com/safari-cors-lameness/Blop-Mark_DiAngelo.mp3");
  },
  create: function() {
    var fly = game.add.sprite(120, 57, "fly");
    var blop = game.add.audio("blop");

    fly.animations.add("flying", [0,1,2,3,4,5,6,7,8,9], 10, true);
    fly.animations.play("flying");
    game.stage.backgroundColor = 0xf0f0f0;
    game.time.events.loop(1000, blop.play.bind(blop));
  },
});
</script>

The above code, which you can try out live at http://jsbin.com/yolola/2/, works fine on Firefox 33, Internet Explorer 11, and Chrome 38. It also works on Safari 8.0 for the first page load, after which subsequent page refreshes fail. When it fails, the following appears in the Safari developer console:

[Error] Cross-origin image load denied by Cross-Origin Resource Sharing policy.
[Warning] Phaser.Loader error loading file: fly from URL https://s3.amazonaws.com/safari-cors-lameness/fly-flying.png (phaser.min.js, line 16)
[Error] XMLHttpRequest cannot load https://s3.amazonaws.com/safari-cors-lameness/Blop-Mark_DiAngelo.mp3. Origin http://jsbin.com is not allowed by Access-Control-Allow-Origin.
[Warning] Phaser.Loader error loading file: blop from URL https://s3.amazonaws.com/safari-cors-lameness/Blop-Mark_DiAngelo.mp3

Viewing the page successfully again requires manually clearing Safari's cache.

This appears to be due to an idiosyncrasy or bug in Safari having to do with the way it caches CORS-enabled resources, which is documented in CreateJS/PreloadJS#46. The first comment in that issue also reveals a potential workaround for the problem, which may or may not be translatable to Phaser.

I am okay with this bug being marked as "won't fix" because it's likely Safari's fault, not Phaser's, but I figured I would document the problem here anyways, just so it's easy to find and reproduce in the future.

Note: While I am confident that the the S3 bucket at safari-cors-lameness (which the assets in my example are being retrieved from) has a correct CORS policy, I'm including it below for reference, just in case I am horribly mistaken.

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions