HTML for Apple devices to mitigate POST fragmentation (#3069)
This commit is contained in:
parent
95fc8b14b3
commit
c50b4789c4
|
@ -0,0 +1,322 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
|
||||
<title>WiFi Login</title>
|
||||
<style type=text/css>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
font-family: sans-serif;
|
||||
text-align: center;
|
||||
background: #444d44;
|
||||
}
|
||||
|
||||
#content {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 320px;
|
||||
height: 480px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
input,
|
||||
button,
|
||||
select {
|
||||
-webkit-appearance: none;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
border: 0;
|
||||
box-shadow: 0 0 15px 1px rgba(0, 0, 0, .4);
|
||||
box-sizing: border-box;
|
||||
padding: 20px 30px;
|
||||
background: #fff;
|
||||
min-height: 320px;
|
||||
margin: -1px;
|
||||
}
|
||||
|
||||
input {
|
||||
border: 1px solid #ccc;
|
||||
margin-bottom: 10px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
color: #222;
|
||||
font: 16px monospace;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
select {
|
||||
font: 16px monospace;
|
||||
background-color: transparent;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
button {
|
||||
color: #fff;
|
||||
border: 0;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
font: 16px sans-serif;
|
||||
text-decoration: none;
|
||||
padding: 10px 5px;
|
||||
background: #31b457;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
button:focus,
|
||||
button:hover {
|
||||
box-shadow: 0 0 0 2px #fff, 0 0 0 3px #31b457;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 16px;
|
||||
color: #666;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
color: #ccc;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.utility {
|
||||
float: right;
|
||||
clear: both;
|
||||
max-width: 75%;
|
||||
font-size: 13px;
|
||||
color: #222;
|
||||
margin: 10px 0;
|
||||
padding: 5px 10px;
|
||||
background: #ccc;
|
||||
}
|
||||
|
||||
.utility:focus,
|
||||
.utility:hover {
|
||||
box-shadow: 0 0 0 2px #fff, 0 0 0 3px #ccc;
|
||||
}
|
||||
|
||||
#dropdown,
|
||||
#f2,
|
||||
#f3,
|
||||
#bk2 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#dropdown {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
height: 51px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#aplist {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
border: 1px solid #ccc;
|
||||
font-family: monospace;
|
||||
padding: 10px 5px;
|
||||
}
|
||||
|
||||
#arrow {
|
||||
color: #888;
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
top: 15px;
|
||||
}
|
||||
|
||||
#i {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id=content>
|
||||
<fieldset>
|
||||
<div id=deviceId></div>
|
||||
<div id=f1>
|
||||
<h3>Connect device to your Wi-Fi</h3>
|
||||
<button id=networks type=button class=utility></button>
|
||||
<div id=dropdown>
|
||||
<span id=arrow>▼</span>
|
||||
<select id=aplist name=aplist></select>
|
||||
</div>
|
||||
<input id=ssid type=text autocorrect=off autocapitalize=none placeholder='Wi-Fi Name' />
|
||||
<input id=wifi_password type=text autocorrect=off autocapitalize=none autocomplete=off placeholder=Password />
|
||||
<button id=submit type=button>Save</button>
|
||||
</div>
|
||||
<div id=f2>
|
||||
<h1>Success!</h1>
|
||||
<div id=i>
|
||||
<h3>Your device has successfully connected to the Wi-Fi network.<br /><br/>You may now close this web page.</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div id=f3>
|
||||
<h2>Trying...</h2>
|
||||
<button id=bk2 type=button class='utility'>Go Back to Wi-Fi Setup</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
<h4 id='st'>Updating Status...</h4>
|
||||
</div>
|
||||
<script>
|
||||
var $ = function (selector) { return document.querySelector(selector); };
|
||||
var ab = $('#networks'), ap = $('#aplist');
|
||||
var stopAll = false, ra, rs, submitted = false;
|
||||
|
||||
function show(f, y) {
|
||||
if (y == null) y = f;
|
||||
$(f).style.display = y == f ? 'block' : 'none';
|
||||
}
|
||||
function hide(f) {
|
||||
$(f).style.display = 'none';
|
||||
}
|
||||
function to(cb, x) {
|
||||
return setTimeout(cb, 1000 * x);
|
||||
}
|
||||
function refr() {
|
||||
if (!stopAll)
|
||||
fetch('/status.json?n=' + Math.random(), 'GET', newSt, 2);
|
||||
}
|
||||
function cur(f) {
|
||||
show('#f1', f);
|
||||
show('#f2', f);
|
||||
show('#f3', f);
|
||||
}
|
||||
function newSt(s, d) {
|
||||
clearTimeout(rs);
|
||||
rs = to(refr, 3);
|
||||
|
||||
if (s != 200) {
|
||||
$('#st').innerText = 'Awaiting Status (' + s + ')';
|
||||
} else {
|
||||
if (typeof d === 'string') {
|
||||
d = JSON.parse(d);
|
||||
}
|
||||
|
||||
$('#deviceId').innerText = "Device: " + d.deviceid;
|
||||
|
||||
var c = d.pairing;
|
||||
|
||||
var st = [
|
||||
'Idle',
|
||||
'Connecting...',
|
||||
'Failed - wrong password',
|
||||
'Failed - network not found',
|
||||
'Failed',
|
||||
'Wi-Fi successfully connected!'
|
||||
][d.status];
|
||||
|
||||
if (st == null)
|
||||
st = "";
|
||||
|
||||
if (!submitted && d.status > 1 && d.status < 5)
|
||||
st = "Need a valid Network and Password";
|
||||
|
||||
$('#st').innerText = st;
|
||||
|
||||
if (d.status === 5) {
|
||||
cur('#f2');
|
||||
stopAll = true;
|
||||
clearTimeout(ra);
|
||||
} else if (d.status > 1) {
|
||||
cur('#f1');
|
||||
}
|
||||
}
|
||||
}
|
||||
function submit() {
|
||||
submitted = true;
|
||||
var url = '/update?wifi_ssid=' + encodeURIComponent($('#ssid').value) + '&wifi_password=' + encodeURIComponent($('#wifi_password').value);
|
||||
clearTimeout(rs);
|
||||
fetch(url, 'GET', refr, 2);
|
||||
cur('#f3');
|
||||
}
|
||||
function fetch(url, method, callback, time_out) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.onloadend = function () {
|
||||
callback(xhr.status, xhr.responseText);
|
||||
}
|
||||
xhr.ontimeout = function () {
|
||||
callback(-1, null);
|
||||
}
|
||||
xhr.open(method, url, true);
|
||||
xhr.setRequestHeader('Accept', 'application/json');
|
||||
xhr.timeout = (time_out || 10) * 1000;
|
||||
xhr.send();
|
||||
}
|
||||
function gotAp(s, json) {
|
||||
var list;
|
||||
if (s === 200 && json != null) {
|
||||
if (typeof json === 'string' && json.length > 0) {
|
||||
list = JSON.parse(json);
|
||||
} else if (typeof json === 'object') {
|
||||
list = json;
|
||||
}
|
||||
|
||||
list.sort(function (a, b) {
|
||||
return b.rssi - a.rssi;
|
||||
});
|
||||
var ops = '<option>Select a Network...</option>';
|
||||
for (var i = 0; i < list.length; ++i) {
|
||||
ops += '<option>' + list[i].ssid + '</option>';
|
||||
}
|
||||
ap.innerHTML = ops;
|
||||
ab.disabled = false;
|
||||
togAp(null, true);
|
||||
ab.onclick = togAp;
|
||||
} else {
|
||||
ab.innerText = 'No networks found (' + s + ')';
|
||||
ra = to(refrAp, 5);
|
||||
}
|
||||
}
|
||||
function togAp(ev, force) {
|
||||
if (!force || ap.style.display == 'block') {
|
||||
hide('#dropdown');
|
||||
show('#ssid');
|
||||
ab.innerText = 'Scan for Networks';
|
||||
ab.onclick = refrAp;
|
||||
} else {
|
||||
show('#dropdown');
|
||||
hide('#ssid');
|
||||
ab.innerText = 'Manual Entry';
|
||||
}
|
||||
}
|
||||
function refrAp() {
|
||||
ab.innerText = 'Searching for networks...';
|
||||
ab.disabled = true;
|
||||
ap.innerHTML = '<option disabled>Scanning...</option>';
|
||||
if (!stopAll)
|
||||
fetch('/aplist?n=' + Math.random(), 'GET', gotAp, 10);
|
||||
}
|
||||
window.onload = function() {
|
||||
ab.innerText = 'Scan for Networks';
|
||||
ab.onclick = refrAp;
|
||||
$('#aplist').onchange = function () {
|
||||
$('#ssid').value = $('#aplist').value;
|
||||
};
|
||||
$('#submit').onclick = submit;
|
||||
$('#bk2').onclick = function () {
|
||||
cur('#f1')
|
||||
}
|
||||
rs = to(refr, 0.5);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -6,6 +6,13 @@
|
|||
This module provides a simple way of configuring ESP8266 chips without using a
|
||||
serial interface or pre-programming WiFi credentials onto the chip.
|
||||
|
||||
!!! attention "ATTENTION Apple users"
|
||||
|
||||
Due to bug [#2931](https://github.com/nodemcu/nodemcu-firmware/issues/2931) the configuration does currently not work for many Safari browsers (iOS & macOS).
|
||||
As a **workaround** there is alternative HTML file which uses another method to transfer the login credentials. It does not support sending arbitrary additional configuration parameters and likewise no `eus_params.lua` will be written. The WiFi credentials will be stored in the ESP flash.
|
||||
|
||||
Just copy [enduser_setup_apple.html](../../app/modules/enduser_setup/enduser_setup_apple.html) to the ESP file system and rename it to `enduser_setup.html`.
|
||||
|
||||
After running [`enduser_setup.start()`](#enduser_setupstart), a wireless
|
||||
network named "SetupGadget_XXXXXX" will starting. This prefix can be overridden
|
||||
in `user_config.h` by defining `ENDUSER_SETUP_AP_SSID`. Connect to that SSID
|
||||
|
|
Loading…
Reference in New Issue