广丰卷烟厂数采质量分析系统
zhuguifei
2026-03-02 80ff784bf60637cd348ae665fc907f7b1e527dd8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
<!--
    mitm.html is the lite "man in the middle"
 
    This is only meant to signal the opener's messageChannel to
    the service worker - when that is done this mitm can be closed
    but it's better to keep it alive since this also stops the sw
    from restarting
 
    The service worker is capable of intercepting all request and fork their
    own "fake" response - wish we are going to craft
    when the worker then receives a stream then the worker will tell the opener
    to open up a link that will start the download
-->
<script>
  // This will prevent the sw from restarting
  let keepAlive = () => {
    keepAlive = () => {};
    var ping = location.href.substr(0, location.href.lastIndexOf('/')) + '/ping';
    var interval = setInterval(() => {
      if (sw) {
        sw.postMessage('ping');
      } else {
        fetch(ping).then(res => res.text(!res.ok && clearInterval(interval)));
      }
    }, 10000);
  };
 
  // message event is the first thing we need to setup a listner for
  // don't want the opener to do a random timeout - instead they can listen for
  // the ready event
  // but since we need to wait for the Service Worker registration, we store the
  // message for later
  let messages = [];
  window.onmessage = evt => messages.push(evt);
 
  let sw = null;
  let scope = '';
 
  function registerWorker() {
    return navigator.serviceWorker
      .getRegistration('./')
      .then(swReg => {
        return swReg || navigator.serviceWorker.register('sw.js', { scope: './' });
      })
      .then(swReg => {
        const swRegTmp = swReg.installing || swReg.waiting;
 
        scope = swReg.scope;
 
        return (
          (sw = swReg.active) ||
          new Promise(resolve => {
            swRegTmp.addEventListener(
              'statechange',
              (fn = () => {
                if (swRegTmp.state === 'activated') {
                  swRegTmp.removeEventListener('statechange', fn);
                  sw = swReg.active;
                  resolve();
                }
              })
            );
          })
        );
      });
  }
 
  // Now that we have the Service Worker registered we can process messages
  function onMessage(event) {
    let { data, ports, origin } = event;
 
    // It's important to have a messageChannel, don't want to interfere
    // with other simultaneous downloads
    if (!ports || !ports.length) {
      throw new TypeError("[StreamSaver] You didn't send a messageChannel");
    }
 
    if (typeof data !== 'object') {
      throw new TypeError("[StreamSaver] You didn't send a object");
    }
 
    // the default public service worker for StreamSaver is shared among others.
    // so all download links needs to be prefixed to avoid any other conflict
    data.origin = origin;
 
    // if we ever (in some feature versoin of streamsaver) would like to
    // redirect back to the page of who initiated a http request
    data.referrer = data.referrer || document.referrer || origin;
 
    // pass along version for possible backwards compatibility in sw.js
    data.streamSaverVersion = new URLSearchParams(location.search).get('version');
 
    if (data.streamSaverVersion === '1.2.0') {
      console.warn('[StreamSaver] please update streamsaver');
    }
 
    /** @since v2.0.0 */
    if (!data.headers) {
      console.warn(
        "[StreamSaver] pass `data.headers` that you would like to pass along to the service worker\nit should be a 2D array or a key/val object that fetch's Headers api accepts"
      );
    } else {
      // test if it's correct
      // should thorw a typeError if not
      new Headers(data.headers);
    }
 
    /** @since v2.0.0 */
    if (typeof data.filename === 'string') {
      console.warn(
        "[StreamSaver] You shouldn't send `data.filename` anymore. It should be included in the Content-Disposition header option"
      );
      // Do what File constructor do with fileNames
      data.filename = data.filename.replace(/\//g, ':');
    }
 
    /** @since v2.0.0 */
    if (data.size) {
      console.warn(
        "[StreamSaver] You shouldn't send `data.size` anymore. It should be included in the content-length header option"
      );
    }
 
    /** @since v2.0.0 */
    if (data.readableStream) {
      console.warn('[StreamSaver] You should send the readableStream in the messageChannel, not throught mitm');
    }
 
    /** @since v2.0.0 */
    if (!data.pathname) {
      console.warn('[StreamSaver] Please send `data.pathname` (eg: /pictures/summer.jpg)');
      data.pathname = Math.random().toString().slice(-6) + '/' + data.filename;
    }
 
    // remove all leading slashes
    data.pathname = data.pathname.replace(/^\/+/g, '');
 
    // remove protocol
    let org = origin.replace(/(^\w+:|^)\/\//, '');
 
    // set the absolute pathname to the download url.
    data.url = new URL(`${scope + org}/${data.pathname}`).toString();
 
    if (!data.url.startsWith(`${scope + org}/`)) {
      throw new TypeError('[StreamSaver] bad `data.pathname`');
    }
 
    // This sends the message data as well as transferring
    // messageChannel.port2 to the service worker. The service worker can
    // then use the transferred port to reply via postMessage(), which
    // will in turn trigger the onmessage handler on messageChannel.port1.
 
    const transferable = data.readableStream ? [ports[0], data.readableStream] : [ports[0]];
 
    if (!(data.readableStream || data.transferringReadable)) {
      keepAlive();
    }
 
    return sw.postMessage(data, transferable);
  }
 
  if (window.opener) {
    // The opener can't listen to onload event, so we need to help em out!
    // (telling them that we are ready to accept postMessage's)
    window.opener.postMessage('StreamSaver::loadedPopup', '*');
  }
 
  if (navigator.serviceWorker) {
    registerWorker().then(() => {
      window.onmessage = onMessage;
      messages.forEach(window.onmessage);
    });
  }
 
  // FF v102 just started to supports transferable streams, but still needs to ping sw.js
  // even tough the service worker dose not have to do any kind of work and listen to any
  // messages... #305
  keepAlive();
</script>