pkerspe / ESP-StepperMotor-Server

Turn your ESP32 into a complete stepper motor control server with web UI, REST API and serial control interface
MIT License
225 stars 39 forks source link

UI not showing in ins Safari and Mobile Safari Browser view on iPhone #20

Closed conaito closed 3 years ago

conaito commented 3 years ago

We have test the gui on several browsers.. work on all except on a mobile (iphone se). any idea about? we also try to recompile the gui (vue) but all we try it doesn‘t fix that. we will try soon to provide some debug info iphone/mac

pkerspe commented 3 years ago

It seems there is an issue with the js file. When connecting the iPhone to the Mac and inspecting the console in safari with the web developer feature enabled on the iPhone I can see:

SyntaxError: Invalid character '\u001f'

It seems the iPhone has an issue with gz-compressed files in the way they are sent by the server. You can see the same issue when you call <IP of esp server>/update. The iPhone does not respect the Content-Encoding header in the response and tries to download the gz-compressed file rather than rendering it.

The server answers the request for the compressed file with:

Access-Control-Allow-Methods: GET,POST,PUT,DELETE
Content-Type: text/javascript
Access-Control-Allow-Origin: *
Accept-Ranges: none
Access-Control-Allow-Headers: Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers
Content-Disposition: inline; filename="app.js.gz"
Content-Encoding: gzip
Content-Length: 211038
Connection: close

Content length is correct, encoding is also correct. The content disposition in general is also correct, the "filename" part is actually not needed IMHO but it is generated automatically by the async webserver.

I cannot find any clue on the net what might be wrong. Since it works in all other browsers, it must be some very specific implementation of mobile safari being picky about something. Currently, since this UI was never intended to be used on a mobile screen I cannot investigate more time on this.

Feel free to post a link if you find a solution on the web how to make mobile safari accept gzip encoded files correctly. You can add headers to the response if needed in line 154 of ´ESPStepperMotorServer_WebInterface.cpp´ https://github.com/pkerspe/ESP-StepperMotor-Server/blob/7b7c25f5ad4d53f28cef55ab53a4ed62a99653fc/src/ESPStepperMotorServer_WebInterface.cpp#L154

A workaround that will work: disable the gzip-compression by replacing the gzipped file in the SPIFFS with a non compressed one and changing const char *webUiJsFile = "/js/app.js.gz"; in the webinterface header file with const char *webUiJsFile = "/js/app.js"; and removing line 154 (mentioned above) in the webinterface cpp file. But this will slow downloading of the UI since the js file will be about 850kb instead of 210kb with gzip. I do not think it would be a good idea as a workaround in general, since that would basically be a pain for all other users that do not use mobile safari.

conaito commented 3 years ago

as i read may safari have some problem with gz extension.. so someone talks about using jgz as extension. i also found this code: https://github.com/vitotai/BrewPiLess/blob/master/src/BrewPiLess.cpp

scroll to //workaround for safari

may thats a idea?

pkerspe commented 3 years ago

I don't know from the code how this "jgz" file is created, so unfortunately that does not help. Just figured that even regular safari has this issue, not only mobile safari.

pkerspe commented 3 years ago

ok, in regular Safari and mobile Safari it could be fixed by patching the WebResponses.cpp in ESP Async WebServer Library: line 534 snprintf(buf, sizeof (buf), "inline; filename=\"%s\"", filename); needs to be changed to: snprintf(buf, sizeof (buf), "inline");

pkerspe commented 3 years ago

I created an issue in ESP Async Webserver Project for this matter: https://github.com/me-no-dev/ESPAsyncWebServer/issues/926

Closing this issue here, since it is a Problem in the external library that cannot be fixed in this library (overwriting headers is not possible since the "remove" function from the LinkedList where the headers are stored is not exposed via the ESP Async Webserver API

conaito commented 3 years ago

I found another fix. changing into the ESPStepperMotorServer_WebInterface.h the const char *webUiJsFile = "/js/app.js.jgz"; (Extension jgz) and as well into the data folders the app.js.gz to .jgz (+ into index.html) it also work great now into iphone. :)

pkerspe commented 3 years ago

did you also test in other browsers if it still works there? Not sure if this is a fix or a workaround, but good for you it works! I will way for the external bug to be closed since this seems more appropriate, but good to know, always learning something new.

conaito commented 3 years ago

yes tested in several browsers and works well :) hope that you fast can help us for the switch/encoder issue - must say love the solution and not want change to others