ความแตกต่างระหว่าง Server.Execute และ Execute ใน ASP เพื่อใช้สคริปต์รวมแบบไดนามิก เพื่อนที่ต้องการสามารถอ้างอิงถึงได้ ฉันเพิ่งวางแผนที่จะลองใช้สถาปัตยกรรม MVC ใน ASP มีคนถามฉันว่า: ASP ถูกกำจัดแล้ว ทำไมฉันยังศึกษามันอยู่ ฉันก็รู้เรื่องนี้เช่นกัน เนื่องจาก Microsoft เลิกใช้ ASP 3.0 และเปลี่ยนมาใช้ ASP.NET แล้ว ASP จึงตามหลัง PHP และ JSP มากซึ่งเริ่มต้นเกือบพร้อมกัน . ASP ถูกกล่าวว่าถูกกำจัดออกไปแล้ว ไม่มีใครสามารถช่วยไม่ให้ถูกกำจัดออกไปได้ แต่เป็นที่น่าสังเกตว่า ASP ยังคงแพร่หลายในตลาดจีน โดยเฉพาะอย่างยิ่งสำหรับแอปพลิเคชันบางรายการขององค์กรขนาดเล็กและขนาดกลางบางแห่ง ปัญหาและง่ายต่อการปรับใช้ ในระบบ Windows เก่าบางระบบ ไม่จำเป็นต้องติดตั้ง .NET โดยพื้นฐานแล้วสามารถรันเฟรมเวิร์กได้โดยตรง ดังนั้นจึงยังจำเป็นต้องเตรียมเฟรมเวิร์ก อย่างไรก็ตาม เฟรมเวิร์กของฉันเป็นเฟรมเวิร์กทดลอง เพียงเพื่อตรวจสอบว่า ASP สามารถใช้สถาปัตยกรรม MVC ที่คล้ายกับ PHP ได้หรือไม่
เอาล่ะ พูดมากแล้ว มาเข้าประเด็นกันดีกว่า สาเหตุของปัญหานี้คือฉันต้องรวมไฟล์ ASP แบบไดนามิก ดังที่เราทุกคนทราบกันดีว่ามีวิธีรวมเพียงวิธีเดียวใน ASP ซึ่งก็คือ SSI (รวมฝั่งเซิร์ฟเวอร์) ซึ่งโดยพื้นฐานแล้วแบ่งออกเป็นสองประเภทดังต่อไปนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
<!-- #include file=sample.asp -->
<!-- #include virtual=sample.asp -->
โดยพื้นฐานแล้ว อันแรกจะใช้กันทั่วไปมากกว่าในทั้งสอง #include virtual มีพาธเสมือน ซึ่งโดยทั่วไปจะใช้ในไดเร็กทอรีเสมือน แต่ทั้งสองสิ่งนี้เป็นแบบคงที่ หากเราต้องการรวมมันแบบไดนามิก มันไม่สามารถเขียนเป็น:
คัดลอกรหัสรหัสดังต่อไปนี้:
<!-- #include file=<%=MyVar%> -->
<!-- #include virtual=<%=MyVar%> -->
การเขียนข้างต้นไม่ถูกต้อง เป็นที่เข้าใจได้ว่าคำสั่ง #include จะถูกดำเนินการก่อนที่ ASP จะสตาร์ทเอ็นจิ้นสคริปต์และดำเนินการสคริปต์ระหว่างแท็ก ASP<% %> กล่าวอีกนัยหนึ่ง #include ไม่ใช่งานของ ASP โปรแกรมเซิร์ฟเวอร์ เช่น งานแปล IIS จึงไม่ใส่ใจกับโค้ด ASP ของคุณ
วิธีการใช้วิธีสคริปต์รวมแบบไดนามิกที่คล้ายกับของ PHP ได้แก่ include, include_once, need และ need_once ลองดูที่วิธีการของวัตถุเซิร์ฟเวอร์ ASP: Server.Execute เมื่อค้นหาคุณลักษณะ ASP ทั้งหมด เราจะพบว่าฟังก์ชันนี้คล้ายกับการรวมแบบไดนามิกมากที่สุด เราสามารถทำการทดลองได้:
ตัวอย่าง.inc.asp
คัดลอกรหัสรหัสดังต่อไปนี้:
-
ตอบกลับเขียน Hello World!
-
ทดสอบ.asp
คัดลอกรหัสรหัสดังต่อไปนี้:
-
Server.Execute Sample.inc.asp
Response.Write ฉันเป็น test.asp!
-
ผลลัพธ์จริงควรเป็น Hello World!I am test.asp! ซึ่งระบุว่า Server.Execute สามารถทำงานได้ดีกับการรวมแบบไดนามิก แต่จะเกิดอะไรขึ้นหากฉันต้องการรวมคลาสหรือฟังก์ชันด้วย ต่อไปทำการทดลองดังต่อไปนี้:
ตัวอย่าง.class.asp
คัดลอกรหัสรหัสดังต่อไปนี้:
-
ตัวอย่างชั้นเรียน
จบคลาส
-
ทดสอบ.asp
คัดลอกรหัสรหัสดังต่อไปนี้:
-
Server.Execute ตัวอย่าง.class.asp
Response.Write TypeName (Eval (ตัวอย่างใหม่))
-
เรียกใช้โดยตรงและไม่ได้กำหนดข้อผิดพลาด Microsoft VBScript runtime error '800a01fa' class: 'Sample' ผลลัพธ์น่าผิดหวังมาก เหตุใดจึงเกิดเหตุการณ์เช่นนี้ ฉันตรวจสอบ MSDN และพบคำอธิบายนี้: หากไฟล์ถูกรวมไว้ในเพจการโทรโดยใช้ #include การดำเนินการ .asp จะไม่ใช้มัน ตัวอย่างเช่น คุณอาจมีรูทีนย่อยในไฟล์ที่รวมอยู่ในเพจการโทรของคุณ แต่การดำเนินการ .asp จะไม่รู้จักชื่อรูทีนย่อย ดูเหมือนว่าจะแตกต่างจากปัญหาที่ฉันพบอยู่บ้าง จากนั้นทำการทดลองดังต่อไปนี้:
ตัวอย่าง.inc.asp
คัดลอกรหัสรหัสดังต่อไปนี้:
-
ดิม มายวาร์
MyVar = ฉันคือตัวอย่าง!
-
ทดสอบ.asp
คัดลอกรหัสรหัสดังต่อไปนี้:
-
ดิม มายวาร์
MyVar = ฉันกำลังทดสอบ!
Server.Execute Sample.inc.asp
ตอบกลับเขียน MyVar
-
ผลลัพธ์คือ ฉันกำลังทดสอบ! ซึ่งน่าผิดหวังมาก! ดูเหมือนว่า Server.Execute จะแยกตัวแปร ฟังก์ชัน คลาส และโค้ดอื่นๆ ออกไป ซึ่งหมายความว่าการเรียกสิ้นสุดและการโทรสิ้นสุดจะไม่รบกวนซึ่งกันและกันในระดับโค้ด ดูเหมือนว่า Server.Execute สามารถใช้เพื่อรวม . เทมเพลต asp
ต่อไปนี้คือคุณลักษณะสคริปต์ VBScript Execute สิ่งที่ส่งผ่านไปยัง Execute ต้องเป็นโค้ดสคริปต์ VBScript ที่ถูกต้อง และ Execute จะขึ้นอยู่กับบริบทที่เราต้องการ
ทดสอบ.asp
คัดลอกรหัสรหัสดังต่อไปนี้:
-
ดำเนินการตัวอย่างคลาส: สิ้นสุดคลาส
Response.Write TypeName (Eval (ตัวอย่างใหม่))
-
โค้ดด้านบนแสดงชื่อประเภทตัวอย่างที่เราต้องการได้สำเร็จ เป็นการพิสูจน์ว่า Execute สามารถคำนึงถึงบริบทได้ แต่ปัญหาคือการใช้ Execute เพื่อรวมไฟล์ asp นั้นไม่สะดวกเท่ากับ Server.Execute Execute มาพร้อมกับสคริปต์ VBScript เท่านั้น ดังนั้นเนื้อหาไฟล์จึงต้องอ่านครั้งเดียว ประการที่สอง ไม่สามารถระบุบางแท็กที่ใช้ระบุ ASP ได้ เช่น <% %> มีวิธีเรียกคล้ายกับ <%=MyVar %> ดังนั้นคุณต้องกรอง < % %> จากนั้นแปลง <%=MyVar %> เป็น Response.Write MyVar. เนื่องจากสิ่งที่ฉันต้องการคือการรวมไฟล์คลาส <%=MyVar %> จะไม่ปรากฏขึ้น ฉันเพียงแค่ต้องแทนที่ <% %> สำหรับการอ่านเนื้อหาไฟล์และยกเว้น <% %> คุณสามารถอ้างถึงฟังก์ชันต่อไปนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
ฟังก์ชั่น file_get_contents (ชื่อไฟล์)
สลัว fso, f
ตั้งค่า fso = Server.CreateObject (Scripting.FilesystemObject)
ตั้งค่า f = fso.OpenTextFile(Server.MapPath(ชื่อไฟล์), 1)
file_get_contents = f.อ่านทั้งหมด
ฉ.ปิด
เซต f = ไม่มีเลย
ตั้งค่า fso = ไม่มีเลย
ฟังก์ชันสิ้นสุด
ฟังก์ชั่น class_get_contents (ชื่อไฟล์)
เนื้อหาสลัว
เนื้อหา = file_get_contents (ชื่อไฟล์)
เนื้อหา = แทนที่ (เนื้อหา < & %, )
เนื้อหา = แทนที่ (เนื้อหา % & >, )
class_get_contents = เนื้อหา
ฟังก์ชันสิ้นสุด
ด้วยฟังก์ชันข้างต้น เราสามารถทดสอบโค้ดต่อไปนี้ได้โดยตรง:
ตัวอย่าง.class.asp
คัดลอกรหัสรหัสดังต่อไปนี้:
-
ตัวอย่างชั้นเรียน
จบคลาส
-
ทดสอบ.asp
คัดลอกรหัสรหัสดังต่อไปนี้:
-
ดำเนินการ class_get_contents (Sample.class.asp)
Response.Write TypeName (Eval (ตัวอย่างใหม่))
-
ผลลัพธ์ที่ได้คือชื่อประเภทตัวอย่างที่เราคาดไว้ ดูเหมือนว่า Execute ยังคงทรงพลังมากจริงๆ เพราะผู้ที่มีเจตนาไม่ดีมักจะใช้มันเพื่อสร้างม้าโทรจันแบบประโยคเดียวที่ง่ายที่สุด ประโยคต่อไปนี้:
คัดลอกรหัสดังนี้: <%Execute Request(c)%>
เช่น สคริปต์นี้อยู่ใน file.asp แล้วส่งต่อเป็น file.asp?c=Trojan text ฮ่าๆ คุณรู้อยู่แล้วว่าเรื่องต่อไปนี้ โอเค นี่เป็นการพูดนอกเรื่อง อีกสิ่งหนึ่งที่ควรทราบเกี่ยวกับ Execute ก็คือมันเกี่ยวข้องกับบริบท ดังนั้น ให้ใส่ใจกับปัญหาขอบเขต หาก Execute ตั้งอยู่ภายในกระบวนการย่อยหรือฟังก์ชันฟังก์ชัน จะไม่สามารถเข้าถึงได้จากภายนอก