เนื่องจากระบบเว็บไซต์มีขนาดใหญ่ขึ้นเรื่อยๆ คุกกี้จากชื่อโดเมนที่แตกต่างกันและแม้กระทั่งเว็บไซต์พันธมิตรที่แตกต่างกันอาจจำเป็นต้องแชร์ไม่มากก็น้อยเมื่อเผชิญกับสถานการณ์นี้ สิ่งที่ทุกคนมักจะนึกถึงคือการใช้ศูนย์เข้าสู่ระบบเพื่อกระจายสถานะคุกกี้ แล้วซิงโครไนซ์โซลูชันต้นทุนสูงขึ้นและการใช้งานมีความซับซ้อนและลำบากมากขึ้น
เนื่องจากคุกกี้เป็นแบบข้ามโดเมน เบราว์เซอร์จึงไม่อนุญาตให้มีการเข้าถึงร่วมกันเลย เพื่อที่จะฝ่าฝืนข้อจำกัดนี้ จึงมีการใช้แผนการใช้งานต่อไปนี้เพื่อแบ่งปันข้อมูลข้ามโดเมนโดยใช้ข้อความไปรษณีย์และที่จัดเก็บในเครื่อง
หลักการค่อนข้างง่าย แต่พบข้อผิดพลาดมากมาย มาจัดเรียงที่นี่และทำการสำรองข้อมูลกัน
2. การออกแบบ APIตามที่กล่าวไว้ในเบื้องหลัง เราใช้พื้นที่เก็บข้อมูลในเครื่องแทนคุกกี้ มีความแตกต่างบางประการในการใช้งานระหว่างพื้นที่เก็บข้อมูลในเครื่องและคุกกี้ ตัวอย่างเช่น พื้นที่เก็บข้อมูลในเครื่องมีความจุมากกว่าแต่ไม่มีเวลาหมดอายุ เบราว์เซอร์ที่แตกต่างกัน ขีดจำกัดบนของพื้นที่ทำให้ง่ายต่อการหยุดทำงานหากการทำงานไม่ดี นอกจากนี้ แม้ว่า postmesage จะรองรับข้ามโดเมน แต่ปัญหาด้านความปลอดภัยและ API แบบอะซิงโครนัสยังนำมาซึ่งปัญหาในการใช้งานอีกด้วย ใช้งานง่ายกว่า?
มาดู API ที่ฉันออกแบบก่อน:
import { crosData } from 'base-tools-crossDomainData';var store = new crosData({ iframeUrl:somefile.html, //Shared iframe address, iframe มีข้อกำหนดพิเศษ, ดูไฟล์เทมเพลตหมดอายุ:'d,h,s' / /เวลาหมดอายุเริ่มต้นเป็นวัน ชั่วโมง วินาที สามารถเขียนทับได้เมื่อปลูก});store.set('key','val',{ หมดอายุ:'d,h,s' //option สามารถนำเวลาหมดอายุมาแทนที่หมดอายุ}).then((data)=>{ //วิธีการอะซิงโครนัส หากล้มเหลว มันจะเข้าสู่เหตุการณ์ catch //data {val:'val',key:'key',domain :' โดเมน'};}).catch((err)=>{ console.log(err);}); store.get('key',{ โดเมน:'(.*).sina.cn' //คุณสามารถระบุชื่อโดเมน หรือคุณสามารถใช้ (.*) เพื่อจับคู่สตริงปกติ ข้อมูล val ที่ส่งคืนจะรวมข้อมูลโดเมนไว้ด้วย หากไม่ได้กรอกก็จะส่งคืนโดเมนท้องถิ่น }). จากนั้น ((vals) =>{ console.log (val) //รับข้อมูลที่เก็บไว้แบบอะซิงโครนัส อาจมีหลายรายการ เป็นอาร์เรย์ [{},{}]}).catch((err)=>{});store.clear ('คีย์').แล้ว().จับ(); //เฉพาะคีย์ภายใต้โดเมนปัจจุบันเท่านั้นที่ไม่ได้รับอนุญาตให้ล้างได้ไม่ว่าโมดูลจะใช้งานได้เร็วหรือไม่นั้นขึ้นอยู่กับ API ดังนั้นสำหรับโมดูลการแบ่งปันข้อมูล ฉันคิดว่ามันเป็นเรื่องปกติที่จะสนับสนุนวิธีการตั้งค่า รับ และล้างสามวิธี เนื่องจากข้อความหลังข้อความนั้นเป็นพฤติกรรมอะซิงโครนัสแบบครั้งเดียวและทำเสร็จแล้ว และต้องบรรจุเป็นสัญญาให้เหมาะสมและใช้งานง่ายยิ่งขึ้น เนื่องจากที่เก็บข้อมูลในตัวเครื่องไม่รองรับเวลาหมดอายุ จึงจำเป็นต้องมีการกำหนดค่าเวลาหมดอายุทั่วโลก แน่นอนว่าสามารถกำหนดค่าแยกกันในระหว่างการตั้งค่าได้ เมื่อได้รับ เราสามารถระบุเพื่อรับข้อมูลภายใต้โดเมนหรือข้อมูลภายใต้หลายโดเมนได้ เนื่องจากชื่อคีย์ อาจทำซ้ำได้แต่มีเพียงโดเมนเดียวเท่านั้น สิ่งนี้เกี่ยวข้องกับการจัดการข้อมูล เราจะพูดถึงมันแยกกันในภายหลัง สุดท้ายนี้ API ที่ชัดเจนและตั้งค่าได้จะปลูกฝังข้อมูลในโดเมนนี้เท่านั้นและไม่สามารถดำเนินการข้อมูลในโดเมนอื่นได้
มาดูการตั้งค่าไคลเอนต์และ API กัน:
<!DOCTYPE html><html> <head> <meta charset=utf-8> <title>crosData</title> </head> <body> <script> window.CROS = { โดเมน:/(.*) sina.cn/, //หรือชื่อโดเมนที่คุณอนุญาต รองรับปกติและ * wildcards lz:false //ไม่ว่าจะเปิดใช้งานการบีบอัด lz ของอักขระ val}; </script> <script src=http://cdn/sdk.js></script> </body></html>คุณสามารถแนะนำ js sdk ของลูกค้าในเอกสาร html ในโดเมนใดก็ได้ จากนั้นกำหนดค่ารายการโดเมนที่อนุญาตให้คุณปลูกในโดเมนที่เอกสารนี้ตั้งอยู่ผ่านแอตทริบิวต์ส่วนกลาง และรองรับนิพจน์ทั่วไป จากนั้น lz จะเป็นเช่นนั้น เริ่มการบีบอัด lz-string ฉันจะแนะนำการบีบอัด lz ในภายหลัง
ณ จุดนี้ การออกแบบ API ที่ค่อนข้างทั่วไปเสร็จสมบูรณ์แล้ว มาดูหลักการนำไปใช้และประเด็นเฉพาะบางประการกัน
3. หลักการปฏิบัติฟังดูง่ายมาก แต่จริงๆ แล้วไม่ได้เขียนไว้เลย ก่อนอื่นเราต้องรู้วิธีใช้ postMessage นี่เป็น API ที่พบบ่อยมาก มีจุดสำคัญประการหนึ่งที่จะบอกคุณในที่นี้ นั่นคือ postMessage สามารถใช้ได้ใน iframe เท่านั้น หรือใช้หน้าต่าง .open เป็นวิธีเปิดหน้าใหม่เพื่อสื่อสารกัน แน่นอนว่าก่อนอื่นเราต้องสร้าง iframe ที่ซ่อนอยู่สำหรับข้ามโดเมน
ฉันขี้เกียจเกินไปที่จะใช้เครื่องมือในการวาดภาพ เพราะกระบวนการนี้ค่อนข้างชัดเจน ในที่นี้ ฉันจะเล่ากระบวนการสื่อสารทั้งหมดอีกครั้งด้วยคำพูด ขั้นแรกให้เพจหลักสร้าง iframe ที่ซ่อนอยู่ จากนั้นเมื่อคำสั่งต่างๆ เช่น set, get, clear ฯลฯ จะถูกดำเนินการ ข้อความจะถูกเผยแพร่ผ่าน postMessage หลังจากที่เพจได้รับข้อความแล้ว จะแยกวิเคราะห์คำสั่ง ข้อมูล และ ID โทรกลับ (postMessage ไม่สามารถส่งผ่านฟังก์ชันและการอ้างอิงได้เนื่องจากปัญหาความเข้ากันได้ วิธีที่ดีที่สุดคือส่งผ่านประเภทสตริงเท่านั้น ดังนั้นข้อมูลจึงต้องเข้มงวด) จากนั้นเมื่อเพจย่อยเสร็จสิ้นการดำเนินการ localstorage มันจะส่งคืน cbid และข้อมูลที่เกี่ยวข้องไปยังเพจหลักผ่าน postMessage
4. การเข้ารหัสมีเพียงไม่กี่บรรทัด มาเริ่มเขียนโค้ดกันดีกว่า:
ขั้นแรก เรามาแนะนำแพ็คเกจของบุคคลที่สามที่เราใช้และทำไมเราถึงใช้แพ็คเกจเหล่านั้น:
1. url-parse แยกวิเคราะห์ url โดยส่วนใหญ่จะใช้แอตทริบิวต์ origin ในนั้น เนื่องจาก postMessage เองมีการตรวจสอบแหล่งที่มาอย่างเข้มงวด และเรายังจำเป็นต้องสนับสนุน whitelist และการจัดการชื่อโดเมนด้วย
2. ms เป็นไลบรารีเครื่องมือสำหรับการแปลงตัวย่อเวลาเป็นมิลลิวินาที
3. lz-string เป็นชุดเครื่องมือสำหรับการบีบอัดสตริง ต่อไปนี้เป็นคำแนะนำทางวิทยาศาสตร์ยอดนิยมเกี่ยวกับอัลกอริธึมการบีบอัด LZ ก่อน เพื่อทำความเข้าใจ LZ คุณต้องเข้าใจ RLZ, Run length Encoding ซึ่งเป็นอัลกอริธึมที่ง่ายมากสำหรับการบีบอัดแบบไม่สูญเสียข้อมูล โดยจะแทนที่ไบต์ที่ซ้ำด้วยคำอธิบายง่ายๆ ของไบต์ที่ซ้ำและจำนวนการซ้ำ แนวคิดเบื้องหลังอัลกอริธึมการบีบอัด LZ คือการใช้อัลกอริธึม RLE เพื่อแทนที่การอ้างอิงลำดับไบต์เดียวกันครั้งก่อน พูดง่ายๆ ก็คือ อัลกอริธึม LZ ถือเป็นอัลกอริธึมการจับคู่สตริง ตัวอย่างเช่น: สตริงบางสตริงปรากฏบ่อยครั้งในส่วนข้อความและสามารถแสดงได้ด้วยตัวชี้สตริงที่ปรากฏในข้อความก่อนหน้า
ข้อดีของ lz-string คือสามารถลดความจุในการจัดเก็บของคุณได้อย่างมาก หากใช้ที่เก็บข้อมูลในตัวเครื่องขนาด 5MB เพื่อรองรับการจัดเก็บข้อมูลของชื่อโดเมนหลายชื่อ มันจะถูกบีบอัดและใช้งานได้อย่างรวดเร็ว อย่างไรก็ตาม lz-string เองก็เป็นเช่นนั้น ช้าลงและใช้เงินมากขึ้น หากคุณมีข้อกำหนดด้านขนาดสำหรับจำนวนข้อมูลที่จะส่งในที่ทำงาน คุณสามารถลองใช้อัลกอริธึมการบีบอัดนี้เพื่อปรับความยาวสตริงให้เหมาะสม
4. Localstorage API ของ store2 นั้นค่อนข้างง่าย เพื่อลดความซับซ้อนของตรรกะของโค้ด จึงเลือกไลบรารีการใช้งาน localstorage ที่ได้รับความนิยมเพื่อดำเนินการกับร้านค้า
หลังจากพูดคุยเกี่ยวกับแพ็คเกจจากบุคคลที่สามแล้ว เรามาดูวิธีเขียน js ของหน้าหลักกันดีกว่า:
คลาส crosData { ตัวสร้าง (ตัวเลือก) { supportCheck(); this.options = Object.assign({ iframeUrl: '', หมดอายุ: '30d' }, options); this.cid = 0; this.cbs = {}; .iframeBeforeFuns = []; this.parent = window; this.origin = new url(this.options.iframeUrl).origin; this.createIframe (this.options.iframeUrl); addEvent (this.parent, 'ข้อความ', (evt) => { var data = JSON.parse (evt.data); var origin = evt.origin || evt.OriginalEvent .origin; //ฉันได้รับเฉพาะข้อความของ iframe ที่ฉันเปิด ส่วนข้อความอื่นๆ นั้นผิดกฎหมาย และข้อผิดพลาดจะถูกรายงานโดยตรงหาก (origin !== this.origin) { ปฏิเสธ ('แหล่งกำเนิดที่ผิดกฎหมาย!'); return; if (data.err) { this.cbs[data.cbid].reject(data.err); } else { this.cbs[data.cbid].resolve(data .ret); } ลบ this.cbs[data.cbid] }); frame = document.createElement('iframe'); frame.style.cssText = 'width:1px;height:1px;border:0;position:absolute;left:-9999px;top:-9999px;'; 'src', url); frame.onload = () => { this.child = frame.contentWindow; this.iframeBeforeFuns.forEach(item => item()); } document.body.appendChild(frame); }); } postHandle(ประเภท, args) { คืนสัญญาใหม่ ((แก้ไข, ปฏิเสธ) => { var cbid = this.cid; var message = { cbid: cbid, ต้นกำเนิด: new url (location.href).origin, การกระทำ: ประเภท, args: args } this.child.postMessage(JSON.stringify(message), this.origin); this.cbs[cbid] = { แก้ไข, ปฏิเสธ } this.cid++; }); => { if (this.child) { return this.postHandle(type, args).then(resolve); } else { var self = this; this.iframeBeforeFuns.push(function() { self.postHandle(type, args).then(resolve); }); } }) } set(key, val, options) { options = Object.assign({ หมดอายุ: ms (this.options.expire) }, ตัวเลือก); return this.send('set', [key, val, options]); } get(key, options) { options = Object.assign({ โดเมน: new url(location.href).origin }, options); return this.send('get', [key, options]); } clear(key) { return this.send('clear ', [สำคัญ]); }}อาจมีเพียงไม่กี่วิธีเท่านั้น ต่อไปนี้เป็นประเด็นสำคัญบางประการ ให้ฉันพูดถึงพวกเขา
1. วิธีการรับ ตั้งค่า และล้างเรียกเหมือนกันว่าวิธีการส่ง แต่จะมีการเสริมส่วนของตัวเลือกไว้ด้วย
2. วิธีการส่งส่งคืนออบเจ็กต์สัญญา หากโหลด iframe สำเร็จแล้ว วิธี postHandle จะถูกเรียกโดยตรงเพื่อดำเนินการ postMessage หาก iframe ยังคงโหลดอยู่ การดำเนินการปัจจุบันจะถูกพุชไปยังอาร์เรย์ iframeBeforeFuns และรอให้ iframe onload สิ้นสุด หลังจากการเรียกแบบรวม ฟังก์ชันจะถูกรวมไว้ในเมธอด postHandle
3. เมธอด postHandle จะล้อมข้อมูลก่อนที่จะส่งคำขอและสร้าง cbid, origin, action และ args ออบเจ็กต์ cbs จะบันทึกการแก้ไขและปฏิเสธภายใต้แต่ละ cbid และรอให้ postMessage ของเพจย่อยกลับมาก่อนประมวลผล เนื่องจาก postMessage ไม่สามารถเก็บการอ้างอิงและไม่สามารถส่งผ่านฟังก์ชันได้ วิธีการนี้จึงถูกเลือกที่นี่สำหรับการเชื่อมโยง
4. Constructor นั้นเข้าใจง่าย เมื่อเริ่มต้นคลาสนี้ เราจะกำหนดคุณสมบัติตัวเลือกบางอย่างที่เราต้องการ สร้าง iframe จากนั้นฟังเหตุการณ์ข้อความและประมวลผลข้อความที่ส่งคืนโดยเพจย่อย
5. ในเหตุการณ์ข้อความของเพจหลัก เราต้องตรวจสอบว่าข้อความที่ส่งถึงฉันต้องเป็นหน้าต่าง iframe ที่ฉันเปิด มิฉะนั้นข้อผิดพลาดจะถูกรายงาน จากนั้นการแก้ไขและปฏิเสธใน cbs จะถูกดำเนินการตาม ตัวระบุข้อผิดพลาดในข้อมูล
6. ในเมธอด createIframe การเรียกกลับใน iframe onload จะจัดการวิธีการเรียกของการแคชก่อนการสร้าง ให้ความสนใจกับการใช้ domready ที่นี่ เนื่องจาก sdk อาจถูกดำเนินการก่อนที่จะแยกวิเคราะห์เนื้อหา
นี่คือรหัสสำหรับส่วนลูก:
class iframe { set (key, val, options, origin) { //ตรวจสอบขนาด val ซึ่งต้องไม่เกิน 20k. val = val.toString(); val = this.lz ? lzstring.compressToUTF16(val) valsize = sizeof (val, 'utf16'); // localStorage เก็บไบต์โดยใช้การเข้ารหัส utf16 if (valsize > this.maxsize) { return { ผิดพลาด: 'มูลค่าร้านค้าของคุณ : ' + valstr + ' ขนาดคือ ' + valsize + 'b, ขนาดสูงสุด :' + this.maxsize + 'b , ใช้ utf16' } } key = `${this.prefix_${key}, ${new url(origin).origin}`; var data = { val: val, ล่าสุด: Date.now(), หมดอายุ: Date.now() + options.expire }; store.set(key, data); //หากมากกว่าจำนวนพื้นที่เก็บข้อมูลสูงสุด ให้ลบอันที่อัพเดตล่าสุด if (store.size() > this.storemax) { var Keys = store.keys(); keys.sort( (a, b) => { var item1 = store.get(a), item2 = store.get(b); return item2.lasttime - item1.lasttime; }); var ลบขนาด = Math.abs( นี้.storemax - store.size()); ในขณะที่ (ลบขนาด) { store.remove(keys.pop()); ลบขนาด--; Keys = store.keys(); var regexp = new RegExp('^' + this.prefix + '_' + key + ',' + options.domain + '$'); Keys.filter((key) => { return regexp.test(key); }).map((storeKey) => { var data = store.get(storeKey); data.key = key; data.domain = storeKey .split(',')[1]; if (data.expire < Date.now()) { store.remove(storeKey); } อื่น ๆ { // อัปเดตครั้งล่าสุด; val: data.val, ล่าสุด: Date.now(), หมดอายุ: data.val }); } data.val = this.lz ? lzstring.decompressFromUTF16(data.val) : data.val; filter(item => { return !!item; //Filter unknown }); กลับข้อความ; } clear(key, origin) { store.remove(`${this.prefix__${key},${origin}`); return {}; } clearOtherKey() { //ลบคีย์ที่ผิดกฎหมาย var Keys = store.keys(); new RegExp('^' + this.prefix); key.forEach(key => { if (!keyReg.test(key)) { store.remove(key); } }); } ตัวสร้าง (safeDomain, lz) { supportCheck(); this.safeDomain = safeDomain ||. this.prefix = '_cros'; if (Object.prototype.toString.call(this. safeDomain) !== '[วัตถุ RegExp]') { โยนข้อผิดพลาดใหม่ ('safeDomain ต้องเป็น regexp'); this.lz = lz; this.storemax = 100; this.maxsize = 20 * 1024; // ไบต์ addEvent (หน้าต่าง, 'ข้อความ', (evt) => { var data = JSON.parse (evt.data); var originHostName = new url ( evt .origin).ชื่อโฮสต์; var origin = evt.origin, action = data.action, cbid = data.cbid, args = data.args; // การถ่ายทอดทางกฎหมาย if (evt.origin === data.origin && this.safeDomain.test(originHostName)) { args.push(origin); var whiteAction = ['set', 'get', 'clear'] ; if (whiteAction.indexOf(action) > -1) { var message = this[action].apply(this, args); message.cbid = cbid; window.top.postMessage(JSON.stringify(ข้อความ), origin); } } else { window.top.postMessage(JSON.stringify({ cbid: cbid, err: 'Illegal domain' }) กำเนิด); ; }}มีโค้ดไม่มากนัก ต่อไปนี้เป็นคำแนะนำโดยย่อเกี่ยวกับการใช้งานและความสัมพันธ์ในองค์กรของแต่ละวิธี:
1. ในส่วนของคอนสตรัคเตอร์ คลาสด้านบนยังตรวจสอบการรองรับฟีเจอร์ของเบราว์เซอร์ด้วย จากนั้นจึงกำหนดแอตทริบิวต์ เช่น ค่านำหน้าของร้านค้า จำนวนสูงสุด และขนาดสูงสุดของแต่ละคีย์ จากนั้นเราสร้างช่องทางข้อความและรอให้เพจหลักเรียกมัน
2. ในข้อความ เราจะตรวจสอบที่มาของการออกอากาศ จากนั้นตรวจสอบวิธีการที่เรียกว่า เรียกชุดที่เกี่ยวข้อง รับ และล้างวิธีการ จากนั้นรับผลการดำเนินการ ผูก cbid และสุดท้ายก็ส่งกลับหน้าหลัก postMessage
3. clearOtherKey จะลบข้อมูลการจัดเก็บที่ผิดกฎหมายบางส่วนและเก็บรักษาเฉพาะข้อมูลที่สอดคล้องกับรูปแบบเท่านั้น
4. ในวิธีที่ตั้งค่าไว้ จะมีการดำเนินการตรวจสอบขนาดและการบีบอัด lz กับข้อมูลแต่ละชิ้น ข้อมูลที่บันทึกไว้ประกอบด้วย val, คีย์, เวลาหมดอายุ และเวลาอัปเดต (ใช้สำหรับการคำนวณ LRU)
5. ในวิธีที่ตั้งค่าไว้ หากจำนวน ls ที่เก็บไว้เกินขีดจำกัดสูงสุด จำเป็นต้องมีการดำเนินการลบในขณะนี้ เราสำรวจค่าคีย์ทั้งหมด เรียงลำดับค่าคีย์ ส่งผ่านครั้งสุดท้าย จากนั้นดำเนินการป๊อปอัปของอาร์เรย์คีย์เพื่อรับคีย์ที่ต้องล้างที่ส่วนท้ายของสแต็ก จากนั้นจึงลบออกทีละคีย์ .
6. ในเมธอด get เราจะสำรวจค่าคีย์ทั้งหมด จับคู่คีย์ของโดเมนที่เราต้องการ แล้วแยกส่วนคีย์ในค่าที่ส่งคืน (เราจัดเก็บไว้ในรูปแบบของคีย์และโดเมน) เนื่องจาก API ต้องใช้ค่าที่ตรงกันหลายค่าจึงจะส่งคืน เราสร้างตัวกรองขั้นสุดท้ายสำหรับข้อมูลที่หมดอายุ จากนั้นใช้ lz เพื่อขยายค่า val เพื่อให้แน่ใจว่าผู้ใช้จะได้รับผลลัพธ์ที่ถูกต้อง
ข้างต้นคือกระบวนการเขียนโค้ดและการทบทวนการใช้งานโดยรวมของเรา เรามาพูดถึงข้อผิดพลาดที่พบกันดีกว่า
5. พบข้อผิดพลาดบางประการเนื่องจากให้ไว้แค่โค้ดหลักด้านบนเท่านั้นจึงจะไม่ใช่โค้ดที่สมบูรณ์ เนื่องจากตรรกะนั้นค่อนข้างชัดเจนจึงสามารถเขียนได้ในเวลาอันสั้น มาพูดถึงข้อผิดพลาดด้านล่างกัน
1. คำนวณมูลค่าการจัดเก็บของที่จัดเก็บในตัวเครื่อง
เนื่องจากเราทุกคนทราบดีว่ามีการจำกัดขนาดไว้ 5MB ข้อกำหนดสูงสุดสำหรับข้อมูลแต่ละชิ้นต้องไม่เกิน 20*1024 ไบต์ สำหรับการคำนวณไบต์ ที่เก็บข้อมูลในตัวเครื่องจำเป็นต้องใช้การเข้ารหัส utf16 สำหรับการแปลง โปรดดูที่บทความนี้: การคำนวณอักขระ JS ครอบครองโดยสตริงจำนวนส่วน
2. ความเข้ากันได้
วิธีที่ดีที่สุดคือส่งสตริงใน postMessage ภายใต้ IE8 เหตุการณ์จะต้องราบรื่นและ JSON จะต้องราบรื่น
3. การประมวลผลแบบอะซิงโครนัสเมื่อสร้าง iframe
ที่นี่ ก่อนหน้านี้เราได้ทำการรอแบบเรียกซ้ำสำหรับ setTimeout แต่ต่อมาได้เปลี่ยนเป็นวิธีการนำไปใช้งานข้างต้น หลังจากออนโหลดแล้ว การประมวลผลซ้ำของสัญญาจะได้รับการประมวลผลอย่างสม่ำเสมอเพื่อให้แน่ใจว่า API ของสัญญาจะรวมกันเป็นหนึ่งเดียว
4. เมื่อบันทึกข้อมูล ความซับซ้อนของพื้นที่เทียบกับความซับซ้อนของเวลา
เวอร์ชันแรกไม่ใช่การใช้งานข้างต้น ฉันใช้งาน 3 เวอร์ชัน:
เวอร์ชันแรกจะบันทึกอาร์เรย์ LRU เพื่อลดความซับซ้อนของเวลา แต่จะเปลืองพื้นที่ที่ซับซ้อน นอกจากนี้ หลังจากการทดสอบ วิธีการ get ของร้านค้าค่อนข้างใช้เวลานาน สาเหตุหลักมาจากการใช้เวลานานในการแยกวิเคราะห์
ในเวอร์ชันที่สอง เพื่อเพิ่มอัตราการบีบอัดของ lz-string ให้สูงสุด ฉันจึงบันทึกข้อมูลทั้งหมดรวมถึงอาร์เรย์ LRU ให้เป็นค่าคีย์ ด้วยเหตุนี้ lz-string และ getItem จึงทำให้การใช้เวลาในการแยกวิเคราะห์มีขนาดใหญ่มากเมื่อมี ข้อมูลจำนวนมาก แม้ว่าการคำนวณ ความซับซ้อนของเวลาจะต่ำที่สุด
เวอร์ชันสุดท้ายเป็นเวอร์ชันด้านบน ฉันเสียสละความซับซ้อนของเวลาและความซับซ้อนของพื้นที่ แต่เนื่องจากปัญหาคอขวดอยู่ที่ความเร็วในการอ่านและเขียนของการตั้งค่าและรับ ความเร็วในการอ่านและเขียนของการบันทึกครั้งเดียวจึงเร็วมาก คีย์เป็นเพราะใช้เลเยอร์ด้านล่างสำหรับการจัดเก็บในเครื่องประสิทธิภาพยังคงดีมาก สามารถจัดเก็บได้ 100 รายการใน 20kb และเวลาอ่านและเขียนประมาณ 1 วินาทีประสิทธิภาพดีมาก
6. สรุปและเปรียบเทียบหลังจากเขียนโมดูล ฉันพบว่ามีไลบรารีดังกล่าว: zendesk/cross-storage
แต่ฉันตรวจสอบ API และซอร์สโค้ดของเขาแล้วเปรียบเทียบวิธีการนำไปใช้งาน ฉันคิดว่าเวอร์ชันของฉันมีความสำคัญมากกว่า
1. เวอร์ชันของฉันสามารถควบคุมชื่อโดเมนและการจัดการข้อมูลได้
2. เวอร์ชันสัญญาของ API นั้นเรียบง่ายกว่า โดยมี onConnect น้อยกว่า คุณสามารถอ้างถึงการใช้งานของเขาได้ มันเป็นมากกว่าที่ฉันเขียนไว้มากและไม่ได้แก้ปัญหาของ iframe ที่รอแบบอะซิงโครนัส
3. ไม่รองรับข้อมูลที่บีบอัด LZ
4. ไม่รองรับการจัดการพูลหน่วยเก็บข้อมูล LRU ดังนั้นอาจมีพื้นที่เก็บข้อมูลมากเกินไปจนอาจทำให้การเขียนล้มเหลว
5. ดูเหมือนว่าเขาจะสร้าง iframe สำหรับการโต้ตอบทุกครั้ง ซึ่งเป็นการสิ้นเปลืองการดำเนินการ DOM และการออกอากาศ ฉันคิดว่าไม่มีปัญหาหากเปิดทิ้งไว้ แน่นอนว่าเขาอาจต้องเชื่อมต่อกับไคลเอนต์หลายรายเพื่อที่เขาจะได้จัดการด้วยวิธีนี้ .
สรุปข้างต้นเป็นคำแนะนำของบรรณาธิการเกี่ยวกับปัญหาในการใช้ที่เก็บข้อมูลในตัวเครื่องแทนคุกกี้เพื่อการแบ่งปันข้อมูลข้ามโดเมน ฉันหวังว่ามันจะเป็นประโยชน์กับคุณ หากคุณมีคำถามใดๆ โปรดฝากข้อความถึงฉัน แล้วบรรณาธิการจะตอบกลับคุณ ทันเวลา ฉันอยากจะขอบคุณทุกคนที่ให้การสนับสนุนเว็บไซต์ศิลปะการต่อสู้ VeVb!