แนวทางการทำให้ Use Case การจับคู่รูปแบบทั่วไปเป็นมาตรฐาน
ที่มา
การกำหนดเส้นทางเป็นกุญแจสำคัญของทุกเว็บแอปพลิเคชัน หัวใจสำคัญของการกำหนดเส้นทางคือ การนำ URL ไปใช้ การใช้การจับคู่รูปแบบ หรือตรรกะเฉพาะแอปอื่นๆ กับ URL นั้น และโดยปกติจะแสดงเนื้อหาเว็บตามผลการค้นหา การกำหนดเส้นทางอาจมีหลายวิธี เช่น บางครั้งอาจมีการเรียกใช้โค้ดบนเซิร์ฟเวอร์ที่แมปเส้นทางไปยังไฟล์ในดิสก์ หรือตรรกะในแอปแบบหน้าเดียวที่รอการเปลี่ยนแปลงไปยังตำแหน่งปัจจุบันและสร้าง DOM ที่เกี่ยวข้องเพื่อแสดง
แม้จะไม่มีมาตรฐานที่ชัดเจนเพียงข้อเดียว แต่นักพัฒนาเว็บก็มีแนวโน้มที่จะใช้ไวยากรณ์ทั่วไปสําหรับการแสดงรูปแบบการกำหนดเส้นทาง URL ที่เหมือนกับ regular expressions
อย่างมาก แต่มีการเพิ่มเฉพาะโดเมนบางอย่าง เช่น โทเค็นสําหรับกลุ่มเส้นทางที่ตรงกัน
เฟรมเวิร์กฝั่งเซิร์ฟเวอร์ยอดนิยมอย่าง Express และ Ruby on Rails จะใช้ไวยากรณ์นี้ (หรือโค้ดที่ใกล้เคียงกันมาก) และนักพัฒนา JavaScript สามารถใช้โมดูลอย่าง path-to-regexp
หรือ regexpparam
เพื่อเพิ่มตรรกะนั้นลงในโค้ดของตัวเองได้
URLPattern
เป็นส่วนเพิ่มเติมของแพลตฟอร์มเว็บที่สร้างขึ้นจากรากฐานที่สร้างโดยเฟรมเวิร์กเหล่านี้ โดยมีเป้าหมายเพื่อทำให้ไวยากรณ์รูปแบบการกำหนดเส้นทางเป็นมาตรฐาน รวมถึงการรองรับไวลด์การ์ด กลุ่มโทเค็นที่มีชื่อ กลุ่มนิพจน์ทั่วไป และตัวปรับแต่งกลุ่ม อินสแตนซ์ URLPattern
ที่สร้างด้วยไวยากรณ์นี้สามารถทำงานเกี่ยวกับการกำหนดเส้นทางทั่วไปได้ เช่น การจับคู่กับ URL แบบเต็มหรือ URL pathname
และแสดงข้อมูลเกี่ยวกับโทเค็นและการจับคู่ที่ตรงกันของกลุ่ม
ประโยชน์อีกข้อหนึ่งของการระบุ URL ที่ตรงกันในแพลตฟอร์มเว็บโดยตรงคือ คุณจะแชร์ไวยากรณ์ทั่วไปกับ API อื่นๆ ที่ต้องจับคู่กับ URL ได้ด้วย
การรองรับเบราว์เซอร์และ Polyfill
URLPattern
จะเปิดใช้โดยค่าเริ่มต้นใน Chrome และ Edge เวอร์ชัน 95 ขึ้นไป
ไลบรารี urlpattern-polyfill
มอบวิธีการใช้อินเทอร์เฟซ URLPattern
ในเบราว์เซอร์หรือสภาพแวดล้อม เช่น Node ซึ่งไม่มีการสนับสนุนในตัว หากคุณใช้ Polyfill โปรดตรวจสอบว่าคุณใช้การตรวจหาฟีเจอร์เพื่อให้แน่ใจว่าจะโหลดเฉพาะเมื่อสภาพแวดล้อมปัจจุบันไม่รองรับเท่านั้น มิเช่นนั้น คุณจะสูญเสียประโยชน์ที่สำคัญอย่างหนึ่งของ URLPattern
ซึ่งก็คือการที่สภาพแวดล้อมการสนับสนุนไม่จำเป็นต้องดาวน์โหลดและแยกวิเคราะห์โค้ดเพิ่มเติมเพื่อใช้งาน
if (!(globalThis && 'URLPattern' in globalThis)) {
// URLPattern is not available, so the polyfill is needed.
}
ความเข้ากันได้ของไวยากรณ์
ปรัชญาที่เป็นแนวทางสำหรับ URLPattern
คือการหลีกเลี่ยงสิ่งแปลกใหม่ หากคุ้นเคยกับไวยากรณ์การกำหนดเส้นทางที่ใช้ใน Express หรือ Ruby on Rails อยู่แล้ว ก็ไม่จำเป็นต้องเรียนรู้อะไรใหม่อีก แต่เนื่องจากไวยากรณ์ในไลบรารีการกำหนดเส้นทางยอดนิยมมีความแตกต่างกันเล็กน้อย จึงต้องเลือกไวยากรณ์พื้นฐานเป็นไวยากรณ์พื้นฐาน ผู้ออกแบบ URLPattern
จึงตัดสินใจใช้ไวยากรณ์ของรูปแบบจาก path-to-regexp
(แต่ไม่ใช่แพลตฟอร์ม API) เป็นจุดเริ่มต้น
การตัดสินใจนี้เกิดขึ้นหลังจากการปรึกษาอย่างใกล้ชิดกับผู้ดูแลจัดการคนปัจจุบันของ path-to-regexp
วิธีที่ดีที่สุดในการทำความคุ้นเคยกับหัวใจสำคัญของไวยากรณ์ที่รองรับคือการอ่านเอกสารประกอบสำหรับ path-to-regexp
คุณอ่านเอกสารประกอบที่มีไว้เพื่อเผยแพร่บน MDN ในบ้านปัจจุบันของแพลตฟอร์มได้บน GitHub
ฟีเจอร์เพิ่มเติม
ไวยากรณ์ของ URLPattern
เป็นชุดย่อยของสิ่งที่ path-to-regexp
รองรับ เนื่องจาก URLPattern
รองรับฟีเจอร์พิเศษในไลบรารีการกำหนดเส้นทาง นั่นคือ การจับคู่ต้นทาง รวมถึงไวลด์การ์ดในชื่อโฮสต์ ไลบรารีการกำหนดเส้นทางอื่นๆ ส่วนใหญ่จัดการโดยใช้ pathname และบางครั้งก็ส่วน search หรือ แฮช ของ URL พวกเขาไม่จำเป็นต้องตรวจสอบส่วนต้นทางของ URL เนื่องจากจะใช้สำหรับการกำหนดเส้นทางต้นทางเดียวกันภายในเว็บแอปในตัวเท่านั้น
การคำนึงถึงต้นทางจะช่วยเปิดประตูสู่กรณีการใช้งานเพิ่มเติม เช่น การกําหนดเส้นทางคําขอแบบข้ามต้นทางภายในตัวแฮนเดิลเหตุการณ์ fetch
ของโปรแกรมทำงานของบริการ หากคุณกำหนดเส้นทางเฉพาะ URL ต้นทางเดียวกัน คุณไม่จำเป็นต้องสนใจฟีเจอร์เพิ่มเติมนี้และใช้ URLPattern
เช่นเดียวกับไลบรารีอื่นๆ
ตัวอย่าง
การสร้างรูปแบบ
หากต้องการสร้าง URLPattern
ให้ส่งตัวสร้างสตริงหรือออบเจ็กต์ที่พร็อพเพอร์ตี้มีข้อมูลเกี่ยวกับรูปแบบที่จะจับคู่
การส่งผ่านออบเจ็กต์ช่วยให้คุณควบคุมรูปแบบที่จะใช้ในการจับคู่ส่วนประกอบ URL แต่ละรายการได้อย่างชัดเจนที่สุด ในความละเอียดที่สุด อาจมีลักษณะดังนี้
const p = new URLPattern({
protocol: 'https',
username: '',
password: '',
hostname: 'example.com',
port: '',
pathname: '/foo/:image.jpg',
search: '*',
hash: '*',
});
การระบุสตริงว่างสำหรับพร็อพเพอร์ตี้จะจับคู่เฉพาะในกรณีที่ไม่มีการตั้งค่าส่วนที่เกี่ยวข้องของ URL ไว้ ไวลด์การ์ด *
จะจับคู่ค่าใดก็ได้สำหรับส่วนใดส่วนหนึ่งของ URL
ตัวสร้างมีทางลัดหลายรายการเพื่อการใช้งานที่ง่ายขึ้น การละเว้น search
และ hash
หรือพร็อพเพอร์ตี้อื่นๆ โดยสมบูรณ์จะเทียบเท่ากับการตั้งค่าให้ใช้ไวลด์การ์ด '*'
ตัวอย่างข้างต้นสามารถเข้าใจได้ง่ายเป็น
const p = new URLPattern({
protocol: 'https',
username: '',
password: '',
hostname: 'example.com',
port: '',
pathname: '/foo/:image.jpg',
});
สำหรับทางลัดเพิ่มเติม คุณจะระบุข้อมูลทั้งหมดเกี่ยวกับต้นทางได้ในพร็อพเพอร์ตี้เดียว นั่นคือ baseURL
ซึ่งนำไปสู่
const p = new URLPattern({
pathname: '/foo/:image.jpg',
baseURL: 'https://example.com',
});
ตัวอย่างทั้งหมดนี้จะถือว่า Use Case ของคุณเกี่ยวข้องกับต้นทางที่ตรงกัน หากคุณต้องการจับคู่เฉพาะส่วนอื่นๆ ของ URL โดยยกเว้นต้นทาง (ในกรณีของการกำหนดเส้นทางแบบต้นทางเดียวแบบ "ดั้งเดิม" จำนวนมาก) คุณก็ละเว้นข้อมูลต้นทางทั้งหมดได้เลย และระบุชุดค่าผสมของพร็อพเพอร์ตี้ pathname
, search
และ hash
ได้บางส่วน และเช่นเคย พร็อพเพอร์ตี้ที่ละเว้นจะได้รับการดำเนินการเหมือนกับการตั้งค่าเป็นรูปแบบไวลด์การ์ด *
const p = new URLPattern({pathname: '/foo/:image.jpg'});
อีกทางเลือกหนึ่งในการส่งผ่านในออบเจ็กต์ไปยังตัวสร้าง คุณสามารถระบุสตริง 1 หรือ 2 สตริงก็ได้ หากมีการระบุสตริง 1 สตริง สตริงดังกล่าวควรแสดงรูปแบบ URL แบบเต็ม รวมถึงข้อมูลรูปแบบที่ใช้จับคู่กับต้นทาง หากระบุ 2 สตริง ระบบจะใช้สตริงที่ 2 เป็น baseURL
และจะถือว่าสตริงแรกสัมพันธ์กับฐานนั้น
ไม่ว่าจะระบุ 1 หรือ 2 สตริงก็ตาม ตัวสร้าง URLPattern
จะแยกวิเคราะห์รูปแบบ URL แบบเต็ม แบ่งรูปแบบออกเป็นคอมโพเนนต์ URL และแมปแต่ละส่วนของรูปแบบที่ใหญ่กว่ากับคอมโพเนนต์ที่สอดคล้องกัน ซึ่งหมายความว่าเบื้องหลัง URLPattern
แต่ละรายการที่สร้างขึ้นด้วยสตริงจะแสดงแทนค่าเดียวกับ URLPattern
ที่เทียบเท่าที่สร้างขึ้นด้วยออบเจ็กต์ ตัวสร้างสตริงเป็นเพียงทางลัดสำหรับผู้ที่ต้องการอินเทอร์เฟซแบบละเอียดน้อยกว่า
const p = new URLPattern('https://example.com/foo/:image.jpg?*#*');
เมื่อใช้สตริงเพื่อสร้าง URLPattern
มีข้อควรระวัง 2-3 ข้อที่ควรทราบ
การไม่ใส่พร็อพเพอร์ตี้เมื่อใช้ออบเจ็กต์ในการสร้าง URLPattern
จะเทียบเท่ากับการระบุไวลด์การ์ด *
สำหรับพร็อพเพอร์ตี้นั้น เมื่อมีการแยกวิเคราะห์รูปแบบสตริง URL แบบเต็ม หากคอมโพเนนต์ URL รายการใดรายการหนึ่งไม่มีค่า ระบบจะดำเนินการดังกล่าวเสมือนกับตั้งค่าคุณสมบัติของคอมโพเนนต์เป็น ''
ซึ่งจะจับคู่เมื่อคอมโพเนนต์นั้นว่างเปล่าเท่านั้น
เมื่อใช้สตริง คุณต้องใส่ไวลด์การ์ดอย่างชัดแจ้งหากต้องการนำไปใช้ใน URLPattern
ที่สร้างขึ้น
// p1 and p2 are equivalent.
const p1 = new URLPattern('/foo', location.origin);
const p2 = new URLPattern({
protocol: location.protocol,
hostname: location.hostname,
pathname: '/foo',
search: '',
hash: '',
});
// p3 and p4 are equivalent.
const p3 = new URLPattern('/foo?*#*', location.origin);
const p4 = new URLPattern({
protocol: location.protocol,
hostname: location.hostname,
pathname: '/foo',
});
นอกจากนี้คุณควรทราบว่าการแยกวิเคราะห์รูปแบบสตริงเป็นคอมโพเนนต์อาจให้ความกำกวม มีอักขระอย่างเช่น :
ที่พบใน URL
แต่ยังมีความหมายพิเศษในไวยากรณ์การจับคู่รูปแบบด้วย เพื่อหลีกเลี่ยงความกำกวมนี้ ตัวสร้าง URLPattern
จะสันนิษฐานว่าสัญลักษณ์พิเศษใดๆ เหล่านั้นเป็นส่วนหนึ่งของรูปแบบ ไม่ใช่ส่วนหนึ่งของ URL หากคุณต้องการให้ตีความอักขระที่ไม่ชัดเจนว่าเป็นส่วนหนึ่งของ URL อย่าลืมใช้ Escape ด้วย \` character. For example, the literal URL
about:blankshould be escaped as
'about\:blank'` เมื่อระบุเป็นสตริง
การใช้รูปแบบ
หลังจากสร้าง URLPattern
คุณมี 2 ตัวเลือกในการใช้งาน ทั้งเมธอด test()
และ exec()
จะอินพุตเดียวกันและอัลกอริทึมเดียวกันเพื่อตรวจสอบการจับคู่ แต่ต่างกันที่ค่าที่แสดงผลแตกต่างกันเท่านั้น test()
จะแสดงผล true
เมื่อมีข้อมูลตรงกันสำหรับอินพุตที่กำหนด และ false
หากไม่เป็นเช่นนั้น
exec()
จะแสดงข้อมูลโดยละเอียดเกี่ยวกับการจับคู่พร้อมกับแคปเจอร์กรุ๊ป หรือ null
หากไม่มีข้อมูลที่ตรงกัน ตัวอย่างต่อไปนี้สาธิตโดยใช้ exec()
แต่คุณสลับใช้ test()
เป็นตัวอย่างได้ก็ต่อเมื่อต้องการเฉพาะค่าผลลัพธ์แบบบูลีนที่ไม่ซับซ้อน
วิธีหนึ่งในการใช้เมธอด test()
และ exec()
คือการส่งผ่านสตริง
เช่นเดียวกับที่ตัวสร้างรองรับ หากระบุสตริงเดียว สตริงนั้นควรเป็น URL แบบเต็มซึ่งมีต้นทางด้วย หากระบุ 2 สตริง ระบบจะถือว่าสตริงที่ 2 เป็นค่า baseURL
และจะได้รับการประเมินสตริงแรกโดยสัมพันธ์กับฐานนั้น
const p = new URLPattern({
pathname: '/foo/:image.jpg',
baseURL: 'https://example.com',
});
const result = p.exec('https://example.com/foo/cat.jpg');
// result will contain info about the successful match.
// const result = p.exec('/foo/cat.jpg', 'https://example.com')
// is equivalent, using the baseURL syntax.
const noMatchResult = p.exec('https://example.com/bar');
// noMatchResult will be null.
อีกทางเลือกหนึ่งคือ คุณสามารถส่งออบเจ็กต์ประเภทเดียวกันที่เครื่องมือสร้างรองรับ โดยใช้พร็อพเพอร์ตี้ที่กำหนดให้เฉพาะบางส่วนของ URL ที่คุณสนใจในการจับคู่
const p = new URLPattern({pathname: '/foo/:image.jpg'});
const result = p.exec({pathname: '/foo/:image.jpg'});
// result will contain info about the successful match.
เมื่อใช้ exec()
ใน URLPattern
ที่มีไวลด์การ์ดหรือโทเค็น ค่าการแสดงผลจะให้ข้อมูลเกี่ยวกับค่าที่เกี่ยวข้องใน URL อินพุต วิธีนี้ช่วยให้คุณไม่ต้องแยกวิเคราะห์ค่าเหล่านั้นด้วยตนเอง
const p = new URLPattern({
hostname: ':subdomain.example.com',
pathname: '/*/:image.jpg'
});
const result = p.exec('https://imagecdn1.example.com/foo/cat.jpg');
// result.hostname.groups.subdomain will be 'imagecdn1'
// result.pathname.groups[0] will be 'foo', corresponding to *
// result.pathname.groups.image will be 'cat'
กลุ่มที่ไม่ระบุชื่อและกลุ่มที่มีชื่อ
เมื่อส่งสตริง URL ไปยัง exec()
คุณจะได้รับค่าที่บอกว่าส่วนใดตรงกับกลุ่มของรูปแบบทั้งหมด
ค่าที่ส่งกลับมีพร็อพเพอร์ตี้ที่สอดคล้องกับคอมโพเนนต์ของ URLPattern
เช่น pathname
ดังนั้นหากมีการกำหนดกลุ่มให้เป็นส่วนหนึ่งของส่วน pathname
ของ URLPattern
ค่าที่ตรงกันจะปรากฏใน pathname.groups
ของค่าผลลัพธ์ การจับคู่จะแสดงแตกต่างกันไป
ขึ้นอยู่กับว่ารูปแบบที่สอดคล้องกันเป็นกลุ่มแบบไม่ระบุตัวตนหรือกลุ่มที่มีชื่อ
คุณสามารถใช้ดัชนีอาร์เรย์เพื่อเข้าถึงค่าสำหรับการจับคู่รูปแบบที่ไม่ระบุชื่อ
หากมีรูปแบบที่ไม่ระบุตัวตนหลายรายการ ดัชนี 0
จะแสดงค่าที่ตรงกันของรูปแบบซ้ายสุด พร้อมด้วย 1
และดัชนีอื่นๆ ที่ใช้สำหรับรูปแบบต่อๆ ไป
เมื่อใช้กลุ่มที่ตั้งชื่อในรูปแบบ รายการที่ตรงกันจะแสดงเป็นพร็อพเพอร์ตี้ที่มีชื่อตรงกับชื่อกลุ่มแต่ละชื่อ
การรองรับ Unicode และการทำให้เป็นมาตรฐาน
URLPattern
รองรับอักขระ Unicode ในรูปแบบต่างๆ
กลุ่มที่มีชื่อ เช่น
:café
สามารถมีอักขระ Unicode ได้ กฎที่ใช้สำหรับตัวระบุ JavaScript ที่ถูกต้องจะมีผลกับกลุ่มที่มีชื่อข้อความภายในรูปแบบจะได้รับการเข้ารหัสโดยอัตโนมัติตามกฎเดียวกับที่ใช้สำหรับการเข้ารหัส URL ของคอมโพเนนต์นั้นๆ อักขระ Unicode ภายใน
pathname
จะเข้ารหัสแบบเปอร์เซ็นต์ ดังนั้นรูปแบบpathname
อย่างเช่น/café
จะได้รับการปรับให้เป็นมาตรฐานเป็น/caf%C3%A9
โดยอัตโนมัติ อักขระ Unicode ในhostname
จะได้รับการเข้ารหัสโดยอัตโนมัติโดยใช้ Punycode แทนการเข้ารหัสเปอร์เซ็นต์กลุ่มนิพจน์ทั่วไปต้องมีเฉพาะอักขระ ASCII เท่านั้น ไวยากรณ์นิพจน์ทั่วไปทำให้การเข้ารหัสอักขระ Unicode ในกลุ่มเหล่านี้โดยอัตโนมัติทำได้ยากและไม่ปลอดภัย หากต้องการจับคู่อักขระ Unicode ในกลุ่มนิพจน์ทั่วไป คุณต้องเข้ารหัสเปอร์เซ็นต์ด้วยตนเอง เช่น
(caf%C3%A9)
เพื่อจับคู่café
นอกเหนือจากการเข้ารหัสอักขระ Unicode แล้ว URLPattern
ยังทำ URL ให้เป็นปกติอีกด้วย เช่น /foo/./bar
ในคอมโพเนนต์ pathname
จะถูกยุบไปเป็น /foo/bar
ที่เทียบเท่า
เมื่อมีข้อสงสัยเกี่ยวกับวิธีทำให้รูปแบบอินพุตที่ระบุเป็นมาตรฐาน ให้ตรวจสอบอินสแตนซ์ URLPattern
ที่สร้างขึ้นโดยใช้DevToolsของเบราว์เซอร์
สรุปข้อมูลทั้งหมด
การสาธิต Glitch ที่ฝังอยู่ด้านล่างจะแสดง Use Case หลักของ URLPattern
ภายใน fetch event handler
ของ Service Worker ซึ่งแมปรูปแบบเฉพาะกับฟังก์ชันแบบไม่พร้อมกันซึ่งอาจสร้างการตอบสนองต่อคำขอเครือข่ายได้ แนวคิดในตัวอย่างนี้สามารถนำไปใช้กับสถานการณ์การกำหนดเส้นทางอื่นๆ ได้เช่นกัน ไม่ว่าจะเป็นฝั่งเซิร์ฟเวอร์หรือฝั่งไคลเอ็นต์
ความคิดเห็นและแผนในอนาคต
แม้ว่าฟังก์ชันพื้นฐานของ URLPattern
จะมีใน Chrome และ Edge แล้ว แต่ก็มีแผนที่จะเพิ่มฟีเจอร์เข้ามาอีก บางแง่มุมของ URLPattern
ก็ยังอยู่ระหว่างการพัฒนา และยังมีคำถามที่ยังไม่ได้ตอบอีกหลายข้อเกี่ยวกับพฤติกรรมบางอย่างซึ่งอาจยังคงปรับแต่งได้ เราขอแนะนำให้คุณลองใช้ URLPattern
และแสดงความคิดเห็นผ่านปัญหาเกี่ยวกับ GitHub
การสนับสนุนสำหรับการกำหนดเทมเพลต
ไลบรารี path-to-regexp
มี compile() function
ที่ย้อนกลับลักษณะการทำงานของการกำหนดเส้นทางได้อย่างมีประสิทธิภาพ compile()
จะใช้รูปแบบและค่าสำหรับตัวยึดตำแหน่งโทเค็น แล้วแสดงผลสตริงสำหรับเส้นทาง URL ที่มีค่าเหล่านั้นแทน
เราหวังว่าจะเพิ่มค่านี้ลงในรูปแบบ URL ในอนาคต แต่ไม่อยู่ในขอบเขตของรุ่นแรก
การเปิดใช้ฟีเจอร์แพลตฟอร์มเว็บในอนาคต
สมมติว่า URLPattern
กลายเป็นส่วนหนึ่งของแพลตฟอร์มเว็บไปแล้ว ฟีเจอร์อื่นๆ ที่อาจได้ประโยชน์จากการกำหนดเส้นทางหรือการจับคู่รูปแบบสามารถสร้างเพิ่มเติมมาโดยพื้นฐาน
นอกจากนี้ยังมีการพูดคุยถึงการใช้ URLPattern
สำหรับฟีเจอร์ที่เสนอ เช่น การจับคู่รูปแบบขอบเขตของ Service Worker, PWA เป็นตัวแฮนเดิลไฟล์ และการดึงข้อมูลล่วงหน้าแบบคาดเดา
ข้อความแสดงการยอมรับ
โปรดดูเอกสารอธิบายต้นฉบับสำหรับรายการการรับทราบทั้งหมด