Hi there - I’m accessing some simple php files in order to host a game with highscores. A week ago everything was working fine. Now (even if I roll back the code and project in SVN) it no longer works. All WWW requests just return Unknown Error. The same code works fine in the editor. The WebGL files are being stored and accessed from the same server (same directory) as the php and MySql database are hosted on. I’m completely baffled by this - has anybody encountered this problem or have any idea why Unity has done this? To re-emphasise - the code has not changed since the working version.
Looking at the debug output from the website, it seems to be a case of Cross Origin Request Blocked.
There is some very thin information in the Unity manual about adding some resource headers (what?) to the URL request (huh?). I shouldn’t need to do this because the requests are being hosted on the same web site as the php files - but it might be the only avenue to fix this problem.
So does anybody know what exactly I am supposed to do?
WWW my_request = new WWW(“http://”+ “www.my.website.address/”+“somefile.php”); is my C# code.
do I add the “Access-Control-Allow-Credentials”: “true”, to my_request somehow? Or .htaccess to the root of the server? (I’ve tried and it did nothing) Or to somefile.php? Does this credential stuff need to be all over the place in the php files, or should they be in one place in index.php?
Many thanks anybody who can shed some light on this.
Is it possible that your server stopped serving php files? I had similar error when trying to access *.memgz file, so I had to add this file type to server config. If the files are on the same server, can you use local path instead of http://www… ?
It turned out to be far weirder. my WWW string looked like the following - “http://mysite.thingy.net/blah.php” - and last week it worked absolutely fine from both the editor and when hosted on the server. This week it only worked from the editor - and neither the code nor Unity nor server settings had changed.
It turned out it needed to be “www.mysite.thingy.net” - and whenever this requirement changed,it must have happened at the web hosting company, or in Javascript, or maybe Apache - because it certainly didn’t change in my code.
I hope this helps somebody else, although it’s a very odd bug. Apparently without the www in front of the url, after the http:// bit, the site is treated as non-local because it doesn’t exactly match the site, even though the ‘www’ bit is implied or assumed by most browsers so you might not even notice it’s missing. I don’t fully understand the CORB stuff which is very badly explained in the Unity manual, but this seems to be related. I still don’t know where “Access-Control-Allow-Credentials” is supposed to go.
If you have not been dealing with browser security model before, then it might indeed seem a bit complicated at first, still, there are just a few things that you should know.
First of all I would like to pay your attention to the request url. Unlike most other platforms, in WebGL the main game document has it’s own url, so you can use relative urls in your requests instead of absolute. So if your resource is located on the same domain, then instead ofWWW www = new WWW("http://your-domain/resource-path/resource.php");
you may use the following request (note the leading slash that brings you to the server root)
WWW www = new WWW("/resource-path/resource.php");
or if your game index.html is located in the same folder with the requested resource (i.e.http://your-domain/resource-path/index.html) you may just useWWW www = new WWW("resource.php");
This means that your relative urls will be automatically served from the same origin that the player used to access your game (does not matter whether he usedhttp://www.your-domain orhttps://your-domain, the relative url will belong to the same origin). Note that it is not sufficient for the resource to be located on the same server, as the CORS policy rather deals with ‘origins’ (http://your-domain andhttp://www.your-domain are considered to be different origins, as well ashttp://your-domain andhttps://your-domain)
In cases when you perform a cross-origin request, appropriate CORS headers should be added to the response of the resource server. The simplest case is the Access-Control-Allow-Origin: * header, which can be added in the following ways:
For Apache you may add the following .htaccess file to the server directory, which will add the header for all the files in that directory (considering that the mod_headers module is available):
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
For IIS you may add the following web.config file to the server directory:
You may also add the header directly from the php code, just make sure it is added prior to any output being written (echo etc.):
<?php
header("Access-Control-Allow-Origin: *");
In some cases you might want to restrict the cross-origin access to a specific origin (if your game main document location is known in advance). You may then add the following header to the server response:Access-Control-Allow-Origin: http://your-webgl-domainand provide the matching Origin header in the WWW request (considering that your game index.html will be served from http://your-webgl-domain):
using System.Collections.Generic;
...
Dictionary<string, string> headers = new Dictionary<string, string>();
headers.Add("Origin", "http://your-webgl-domain");
WWW www = new WWW ("http://your-resource-domain/resource-path/resource.php", null, headers);
There are some other CORS response headers that you might consider. In case if your request gets preflighted (i.e. you can see the corresponding OPTIONS request in the browser network profiler) you might want to add appropriate Access-Control-Allow-Methods and Access-Control-Allow-Headers headers. If you are going to make credentialed requests, you might need to add the Access-Control-Allow-Credentials response header. You can find more details on this topic here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
seems to work straight away - and is exactly what I was after. This means I can now run the index.html of the WebGL from my PC and it just communicates instantly. Brilliant! Hopefully this means I can place the WebGL folders and index.html on any web server and it will communicate with the bplaced.net server without any extra CORS stuff (which I confess to not understanding anything about). The relative path name stuff may also come in handy, and is good to know.
Thank you very much! I am especially impressed that you have moved into Unity development after your success at the Battle of Rymnik.