Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

XMLHttpRequest cannot load - Chrome

Discussion in 'WebGL' started by BenJones, Oct 26, 2015.

  1. BenJones

    BenJones

    Joined:
    Dec 14, 2012
    Posts:
    11
    Hey I've been trying to get asset bundles to load and after much trial and error and playing with htaccess files I got Firefox to do it! However Chrome is throwing an error :(

    Here is the WebGL app:
    http://getinspir3d.com/inspir3d-viewer6/index.html



    I am unsure of if my htacess file(s) are set up correctly. Please let me know what changes I need to do if any.

    Here is my htaccess file for the above page:
    Code (CSharp):
    1. <IfModule mod_headers.c>
    2.     SetEnvIf Origin (.*) AccessControlAllowOrigin=$1
    3.     Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
    4.     Header set Access-Control-Allow-Credentials true
    5. </IfModule>
    6.  
    7. Options +FollowSymLinks
    8. RewriteEngine on
    9.  
    10. RewriteCond %{HTTP:Accept-encoding} gzip
    11. RewriteRule (.*)Release(.*)\.js $1Compressed$2\.jsgz [L]
    12. RewriteRule (.*)Release(.*)\.data $1Compressed$2\.datagz [L]
    13. RewriteRule (.*)Release(.*)\.mem $1Compressed$2\.memgz [L]
    14. RewriteRule (.*)Release(.*)\.unity3d $1Compressed$2\.unity3dgz [L]
    15. AddEncoding gzip .jsgz
    16. AddEncoding gzip .datagz
    17. AddEncoding gzip .memgz
    18. AddEncoding gzip .unity3dgz
    I couldn't get the asset bundle to load from the same folder as the app. So it's located here:
    http://getinspir3d.com/inspir3d-viewer4/Patmos.unity3d

    Here is the htaccess file from where the asset bundle is stored:
    Code (CSharp):
    1. Options +FollowSymLinks
    2. RewriteEngine on
    3.  
    4. RewriteCond %{HTTP:Accept-encoding} gzip
    5. RewriteRule (.*)Release(.*)\.js $1Compressed$2\.jsgz [L]
    6. RewriteRule (.*)Release(.*)\.data $1Compressed$2\.datagz [L]
    7. RewriteRule (.*)Release(.*)\.mem $1Compressed$2\.memgz [L]
    8. RewriteRule (.*)Release(.*)\.unity3d $1Compressed$2\.unity3dgz [L]
    9. AddEncoding gzip .jsgz
    10. AddEncoding gzip .datagz
    11. AddEncoding gzip .memgz
    12. AddEncoding gzip .unity3dgz
    13.  
    14. <IfModule mod_headers.c>
    15.     Header always set "Access-Control-Allow-Credentials": "true",
    16.     Header always set "Access-Control-Allow-Headers": "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time",
    17.     Header always set "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
    18.     Header always set "Access-Control-Allow-Origin": "*",
    19. </IfModule>
    20.  
    This is the error I'm getting in Chrome:

    Code (CSharp):
    1. GET http://www.getinspir3d.com/inspir3d-viewer4/Patmos.unity3d _JS_WebRequest_Send @ profile33.js:1fmg @ profile33.js:18ivc @ profile33.js:21Wge @ profile33.js:19TVl @ profile33.js:32invoke_viiii @ profile33.js:1hpk @ profile33.js:5UVl @ profile33.js:32invoke_viiiii @ profile33.js:1gpk @ profile33.js:5CWl @ profile33.js:32invoke_viii @ profile33.js:1Pyg @ profile33.js:18vFk @ profile33.js:5$Wl @ profile33.js:32invoke_iiii @ profile33.js:1XP @ profile33.js:28Lu @ profile33.js:28aQc @ profile33.js:21vId @ profile33.js:13tId @ profile33.js:13EFd @ profile33.js:20tGd @ profile33.js:20AGd @ profile33.js:20vGd @ profile33.js:20uGd @ profile33.js:20Bie @ profile33.js:19$Wl @ profile33.js:32invoke_iiii @ profile33.js:1Brk @ profile33.js:5rVl @ profile33.js:32invoke_iiiii @ profile33.js:1Wyg @ profile33.js:18wQk @ profile33.js:7$Wl @ profile33.js:32invoke_iiii @ profile33.js:1XP @ profile33.js:28Lu @ profile33.js:28aQc @ profile33.js:21wId @ profile33.js:13yGd @ profile33.js:20AGd @ profile33.js:20KJd @ profile33.js:13ang @ profile33.js:18(anonymous function) @ VM157:1SendMessage @ profile33.js:1OnLoaded @ index.html:11(anonymous function) @ VM156:1_JS_Eval_EvalJS @ profile33.js:1ohe @ profile33.js:19KWl @ profile33.js:32invoke_vi @ profile33.js:1dqk @ profile33.js:5CWl @ profile33.js:32invoke_viii @ profile33.js:1bqk @ profile33.js:5TVl @ profile33.js:32invoke_viiii @ profile33.js:1Vyg @ profile33.js:18uFk @ profile33.js:5$Wl @ profile33.js:32invoke_iiii @ profile33.js:1XP @ profile33.js:28Lu @ profile33.js:28aQc @ profile33.js:21vId @ profile33.js:13yGd @ profile33.js:20AGd @ profile33.js:20hGd @ profile33.js:20WIc @ profile33.js:21ind @ profile33.js:20cmg @ profile33.js:18EWl @ profile33.js:32Runtime.dynCall @ profile33.js:1(anonymous function) @ profile33.js:1Browser.mainLoop.runIter @ profile33.js:1Browser_mainLoop_runner @ profile33.js:1
    2. index.html:1 XMLHttpRequest cannot load http://www.getinspir3d.com/inspir3d-viewer4/Patmos.unity3d. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://getinspir3d.com' is therefore not allowed access. The response had HTTP status code 500.
    3. profile33.js:1 NullReferenceException: A null value was found where an object instance was required.
    4. LoadBundle+<DownloadBundle>c__Iterator1.MoveNext ()
    This is the script I wrote to load the asset bundle and instantiate the prefab inside of it:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using System.Collections;
    4.  
    5. public class LoadBundle : MonoBehaviour {
    6.  
    7.     public Transform parent;
    8.  
    9.     public GameObject loadingUI;
    10.  
    11.     public RectTransform progressBar;
    12.     Vector2 progressStart;
    13.  
    14.     Material mat;
    15.  
    16.     void Start()
    17.     {
    18.         mat = gameObject.GetComponent<Renderer>().material;
    19.         progressStart = progressBar.sizeDelta;
    20.         progressBar.sizeDelta = new Vector2(0f, progressStart.y);
    21.         Application.ExternalCall("OnLoaded");
    22.     }
    23.  
    24.     public void Load(string url)
    25.     {
    26.  
    27.         StartCoroutine("DownloadBundle", url);
    28.  
    29.     }
    30.  
    31.     IEnumerator DownloadBundle(string url)
    32.     {
    33.         Debug.Log("Loading = " + url);
    34.         WWW www = new WWW(url);
    35.  
    36.         while (!www.isDone)
    37.         {
    38.             Debug.Log("Progress = " + www.progress * 100f);
    39.             UpdateProgress(www.progress);
    40.             yield return null;
    41.         }
    42.  
    43.         AssetBundle bundle = www.assetBundle;
    44.         string prefabName = "PrefabNotSet";
    45.         bundle.LoadAllAssets();
    46.         foreach(string bundleName in bundle.GetAllAssetNames())
    47.         {
    48.             if (bundleName.Contains(".prefab"))
    49.             {
    50.                 prefabName = bundleName;
    51.             }
    52.             //Debug.Log("checked " + bundleName);
    53.         }
    54.  
    55.         Debug.Log("Before " + prefabName);
    56.         //searches for slash index and gets name of prefab
    57.         int slashIndex = 0;
    58.         for (int i = 0; i < prefabName.Length; i++)
    59.         {
    60.             if (prefabName[i].Equals('/')) { slashIndex = i; }
    61.         }
    62.  
    63.         int nameLength = prefabName.Length - slashIndex - 1;
    64.         prefabName = prefabName.Substring(slashIndex + 1, nameLength);
    65.  
    66.         Debug.Log("After " + prefabName);
    67.  
    68.         GameObject instance = Instantiate(bundle.LoadAsset(prefabName)) as GameObject;
    69.         //GameObject instance = Instantiate(bundle.LoadAsset("patmos" + ".prefab")) as GameObject;
    70.  
    71.         instance.transform.parent = parent;
    72.         instance.transform.position = Vector3.zero;
    73.         instance.transform.eulerAngles = Vector3.zero;
    74.         instance.transform.localScale = Vector3.one;
    75.  
    76.         yield return null;
    77.  
    78.         bundle.Unload(false);
    79.  
    80.         Roof.Instance.SetRoof();
    81.         loadingUI.SetActive(false);
    82.  
    83.     }
    84.  
    85.     void UpdateProgress(float percent)
    86.     {
    87.         progressBar.sizeDelta = new Vector2(percent * progressStart.x, progressStart.y);
    88.     }
    89. }
    90.  
    I've been doing some searching and I think this has to do with CORS.

    My webhost is siteground.com and I have the most basic shared hosting package.

    Anyone run into this problem before? Any suggestions are welcome I'd love some help :)

    Thanks!
    -Ben
     
  2. BenJones

    BenJones

    Joined:
    Dec 14, 2012
    Posts:
    11
  3. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
    I believe the CORS headers need to be set at the root of the site (getinspir3d.com in this case). They're only needed on the server. Right now, however, Im getting HTTP 500 errors trying to access the Patmos.unity3d URL so something is breaking on the server during the request.
     
  4. BenJones

    BenJones

    Joined:
    Dec 14, 2012
    Posts:
    11
    I've been messing with the htaccess files a bit which is why you got a HTTP 500 error. I realized why I was able to get it working in Firefox but not Chrome.

    For some reason the asset bundle downloads for 5 seconds and then stops. Firefox caches that 5 seconds of downloading. Chrome does not. So after 2-3 page refreshes Firefox will finish loading the asset bundle. But Chrome will start over from the beginning each refresh. (i changed the extension of the asset bundle from .unity3d to .jpg for testing purposes)


    Chrome stops at exactly 5 seconds every time:


    I added "Header always set Access-Control-Max-Age "7000"" to my htaccess file thinking maybe it will allow for longer downloads, but it didn't seem to do anything.

    Thanks for the tip sirrus. I already had an htaccess file in the root of my site, so I copied and pasted in the headers:

    This is the root htaccess file:
    Code (CSharp):
    1. # BEGIN WordPress
    2. <IfModule mod_rewrite.c>
    3. RewriteEngine On
    4. RewriteBase /
    5. RewriteRule ^index\.php$ - [L]
    6. RewriteCond %{REQUEST_FILENAME} !-f
    7. RewriteCond %{REQUEST_FILENAME} !-d
    8. RewriteRule . /index.php [L]
    9. </IfModule>
    10.  
    11. # END WordPress
    12. AddType application/octet-stream mem data jsgz datagz memgz
    13. AddType application/octet-stream .mem .data .jsgz .datagz .memgz
    14. AddType application/octet-stream unity3dgz .unity3dgz
    15. AddType application/octet-stream .unity3d unity3d
    16.  
    17. <IfModule mod_headers.c>
    18.     Header always set Access-Control-Max-Age "7000"
    19.     Header always set Access-Control-Allow-Credentials "true"
    20.     Header always set Access-Control-Allow-Headers "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time"
    21.     Header always set Access-Control-Allow-Methods "GET, POST, OPTIONS"
    22.     Header always set Access-Control-Allow-Origin "*"
    23. </IfModule>
    Here is the latest htaccess file which is in the same directory as the webgl app:
    Code (CSharp):
    1. <IfModule mod_headers.c>
    2.     Header always set Access-Control-Max-Age "7000"
    3.     Header always set Access-Control-Allow-Credentials "true"
    4.     Header always set Access-Control-Allow-Headers "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time"
    5.     Header always set Access-Control-Allow-Methods "GET, POST, OPTIONS"
    6.     Header always set Access-Control-Allow-Origin "*"
    7. </IfModule>
    8.  
    9. Options +FollowSymLinks
    10. RewriteEngine on
    11.  
    12. RewriteCond %{HTTP:Accept-encoding} gzip
    13. RewriteRule (.*)Release(.*)\.js $1Compressed$2\.jsgz [L]
    14. RewriteRule (.*)Release(.*)\.data $1Compressed$2\.datagz [L]
    15. RewriteRule (.*)Release(.*)\.mem $1Compressed$2\.memgz [L]
    16. RewriteRule (.*)Release(.*)\.unity3d $1Compressed$2\.unity3dgz [L]
    17. AddEncoding gzip .jsgz
    18. AddEncoding gzip .datagz
    19. AddEncoding gzip .memgz
    20. AddEncoding gzip .unity3dgz
    21.  
    22.  
    Does anyone know why an asset bundle would only download for 5 seconds? I feel like I am getting close to getting this working :)

    Thanks!
    -Ben
     
  5. BenJones

    BenJones

    Joined:
    Dec 14, 2012
    Posts:
    11
    I did some googling for 5 second timeouts and ran across this:
    https://httpd.apache.org/docs/2.4/mod/core.html#keepalivetimeout

    Since I have shared hosting I don't have access to the httpd.conf file, but I found a work around using the htaccess file.

    Here is my lastest htaccess file:
    Code (CSharp):
    1. <ifModule mod_env.c>
    2.   SetEnv KeepAlive On
    3.   SetEnv KeepAliveTimeout 100
    4.   SetEnv MaxKeepAliveRequests 500
    5. </ifModule>
    6.  
    7. <IfModule mod_headers.c>
    8.     Header unset Connection
    9.     Header set Connection keep-alive
    10.  
    11.     Header unset Keep-Alive
    12.     Header set Keep-Alive timeout=100,max=500
    13.  
    14.     Header always set Access-Control-Max-Age "7000"
    15.     Header always set Access-Control-Allow-Credentials "true"
    16.     Header always set Access-Control-Allow-Headers "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time"
    17.     Header always set Access-Control-Allow-Methods "GET, POST, OPTIONS"
    18.     Header always set Access-Control-Allow-Origin "*"
    19.    
    20. </IfModule>
    21.  
    22. Options +FollowSymLinks
    23. RewriteEngine on
    24.  
    25. RewriteCond %{HTTP:Accept-encoding} gzip
    26. RewriteRule (.*)Release(.*)\.js $1Compressed$2\.jsgz [L]
    27. RewriteRule (.*)Release(.*)\.data $1Compressed$2\.datagz [L]
    28. RewriteRule (.*)Release(.*)\.mem $1Compressed$2\.memgz [L]
    29. RewriteRule (.*)Release(.*)\.unity3d $1Compressed$2\.unity3dgz [L]
    30. AddEncoding gzip .jsgz
    31. AddEncoding gzip .datagz
    32. AddEncoding gzip .memgz
    33. AddEncoding gzip .unity3dgz
    34.  
    35.  
    Unfortunately it didn't seem to change anything. It still gets stuck at 5 seconds :(
     
  6. BenJones

    BenJones

    Joined:
    Dec 14, 2012
    Posts:
    11
  7. BenJones

    BenJones

    Joined:
    Dec 14, 2012
    Posts:
    11
    YES!!! It's working!!!
    http://getinspir3d.com/inspir3d-viewer7/index.html

    Updating to 5.2.2f1 did the trick!

    I'm just using the standard htaccess file:
    Code (CSharp):
    1. Options +FollowSymLinks
    2. RewriteEngine on
    3.  
    4. RewriteCond %{HTTP:Accept-encoding} gzip
    5. RewriteRule (.*)Release(.*)\.js $1Compressed$2\.jsgz [L]
    6. RewriteRule (.*)Release(.*)\.data $1Compressed$2\.datagz [L]
    7. RewriteRule (.*)Release(.*)\.mem $1Compressed$2\.memgz [L]
    8. RewriteRule (.*)Release(.*)\.unity3d $1Compressed$2\.unity3dgz [L]
    9. AddEncoding gzip .jsgz
    10. AddEncoding gzip .datagz
    11. AddEncoding gzip .memgz
    12. AddEncoding gzip .unity3dgz
    One thing that is is annoying is my asset bundle loading bar isn't working anymore. It goes from 0 to loaded. I think this might be a bug with the WWW class.
    Code (CSharp):
    1.  WWW www = new WWW(url);
    2.  
    3.         while (!www.isDone)
    4.         {
    5.             Debug.Log("Progress = " + www.progress * 100f);
    6.             UpdateProgress(www.progress);
    7.             yield return null;
    8.         }

    Debug.Log("Progress = " + www.progress * 100f); is being called many times but still is printing out 0, but the model loads. I am testing this in incognito mode so it shouldn't be cached. I'll file a bug report.

    Thanks for the help sirrus :)

    So excited right now :D
     
  8. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
    Glad you got it working. That's always a great feeling :)