Search Unity

Question API Requests not working on WebGL Build

Discussion in 'Scripting' started by rhke, Nov 26, 2022.

  1. rhke

    rhke

    Joined:
    Oct 5, 2022
    Posts:
    8
    Im working on a game that while it works fine in the editor, when I try to build it in WebGL, all the API requests (post/get etc.) hang and never seem to actually make it to the server. Looking at dev tools in browser all I can get is that the request is not finished, and eventually it just times out.


    Code (CSharp):
    1. public bool Post(string dest, string bodyJsonString)
    2. {
    3.   var request = new UnityWebRequest(dest, "POST");
    4.   byte[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(bodyJsonString);
    5.   request.uploadHandler = (UploadHandler) new UploadHandlerRaw(bodyRaw);
    6.   request.SetRequestHeader("Content-Type", "application/json");
    7.   request.SendWebRequest();
    8.   while( !request.isDone )
    9.   {
    10.   }
    11.   request.Dispose();
    12.   return true;
    13. }
    I know that with the way its written the game will hang if the request isn't complete, but Im wondering if theres anything wrong or anything I have to add to make it so that the webgl build will work. Thanks!
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,686
  3. rhke

    rhke

    Joined:
    Oct 5, 2022
    Posts:
    8
    Is this meant to be server side CORS setup?
    I've tried adding
    Code (CSharp):
    1. request.SetRequestHeader("Access-Control-Allow-Origin", "*");
    instead of
    Code (CSharp):
    1. request.SetRequestHeader("Content-Type", "application/json");
    even though the server is expecting a json string but to no avail. Server side it seems as if nothing even arrives in the first place, but maybe I don't understand CORS enough to make modifications server side or see what might be wrong.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,686
    I admit I know almost ZERO about CORS... I just know that I had to serve a crossdomain.xml file from my server to allow WebGL builds of Unity to connect. I did it years and years ago and instead of serving a static file, I made it just another endpoint within my Python that "fabricated" the file and served it.

    This was what I used, you can sorta see what the served text would be from within the print() statements:

    Code (csharp):
    1. # python code:
    2. def    crossdomain(request):
    3.     response = HttpResponse()
    4.     response.write( "<?xml version=\"1.0\" ?>\n")
    5.     response.write( "<cross-domain-policy>\n")
    6.     response.write( "<allow-access-from domain=\"*\" />\n")
    7.     response.write( "</cross-domain-policy>\n")
    8.     return response
    Supposedly that is "wide open" and supposedly that's bad from a security standpoint, but I haven't had issues and I honestly don't care as if something bad happens to my server: I would just nuke it and rebuild it from scratch. There's no meaningful data stored in my case. Your use case may vary. :)
     
  5. rhke

    rhke

    Joined:
    Oct 5, 2022
    Posts:
    8
    Thanks for the tips! Did you also perform any modifications client/game side? Currently running into issues with my server but I'll give this a try as soon as I can!
     
  6. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,987
    Just read the documentation about networking in WebGL. Specifically the section

    CORS is only necessary if you try to access a web resource that is located on a different domain than your actual webGL content. So if you have a seperate server that is hosted on a seperate domain name, this server has to specifically allow access from your other domain or all other domains. It's quite common to use a wildecard, though depending on your API you may restrict access of your API to your WebGL host only.

    For CORS to work the server simply needs to include those access control headers in each response. This can usually be done with an htaccess file if you use an apache / NCSA compatible server and have the header module enabled (
    sudo a2enmod header
    ). See this SO post. If you use a server side scripting language like PHP you can also add those headers inside a script. Though as I said, Cross Domain Resource Sharing (CORS) is only required if you want to access those APIs / resources from a different domain
     
  7. rhke

    rhke

    Joined:
    Oct 5, 2022
    Posts:
    8
    Yeah I realize that bit of code was bad but even so, it shouldn't have prevented API requests from working. CORS is enabled but that didn't initially work. But when I instead used coroutines to send the api requests they no longer hang on the webgl build. Im not sure why using coroutines makes it work in the webgl build when they worked fined without it in the editor though. Thank you all for your help!
     
  8. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,987
    It was completely explained in the documentation I linked and quoted. Websites run in a single thread. So you can not spin-wait on the completion as that one single thread is blocked by your while loop so the webrequest can never finish.