เราส่งคำขอไปยังเซิร์ฟเวอร์เป็นหลักผ่านการส่งสองรูปแบบ: URL และแบบฟอร์ม แบบฟอร์มโดยทั่วไปไม่มีปัญหาที่อ่านไม่ออกและปัญหาที่อ่านไม่ออกส่วนใหญ่อยู่ใน URL ผ่านการแนะนำบล็อกก่อนหน้านี้เรารู้ว่ากระบวนการส่งคำขอการเข้ารหัสไปยังเซิร์ฟเวอร์โดย URL นั้นทำให้เกิดความสับสนมากเกินไป ระบบปฏิบัติการที่แตกต่างกันเบราว์เซอร์ที่แตกต่างกันและชุดอักขระเว็บที่แตกต่างกันจะนำไปสู่ผลลัพธ์การเข้ารหัสที่แตกต่างกันโดยสิ้นเชิง มันน่ากลัวเกินไปหรือไม่ถ้าโปรแกรมเมอร์ต้องการคำนึงถึงผลลัพธ์ทุกอย่าง มีวิธีที่จะทำให้แน่ใจว่าไคลเอนต์ใช้วิธีการเข้ารหัสเพียงวิธีเดียวเพื่อออกคำขอไปยังเซิร์ฟเวอร์หรือไม่?
มี! ที่นี่ส่วนใหญ่ฉันให้วิธีการต่อไปนี้
1. JavaScript
การใช้การเข้ารหัส JavaScript ไม่ได้ทำให้เบราว์เซอร์มีโอกาสเข้าแทรกแซง หลังจากเข้ารหัสแล้วให้ส่งคำขอไปยังเซิร์ฟเวอร์แล้วถอดรหัสในเซิร์ฟเวอร์ เมื่อเรียนรู้วิธีนี้เราต้องการสามวิธีในการเข้ารหัส JavaScript: Escape (), encodeuri () และ encodeuricomponent ()
หนี
สตริงที่ระบุจะถูกเข้ารหัสโดยใช้ชุดอักขระละติน SIO อักขระที่ไม่ใช่ ASCII ทั้งหมดจะถูกเข้ารหัสเป็นสตริงในรูปแบบ %XX โดยที่ XX แสดงถึงหมายเลขเลขฐานสิบหกที่สอดคล้องกับอักขระในชุดอักขระ ตัวอย่างเช่นการเข้ารหัสที่สอดคล้องกับรูปแบบคือ %20 วิธีการถอดรหัสที่สอดคล้องกันคือ Unsescape ()
ในความเป็นจริง Escape () ไม่สามารถใช้โดยตรงสำหรับการเข้ารหัส URL ฟังก์ชั่นจริงของมันคือการส่งคืนค่า Unicode ที่เข้ารหัสของตัวละคร ตัวอย่างเช่นผลลัพธ์ของ "ฉันเป็น CM" ด้านบนคือ %U6211 %U662FCM ซึ่งการเข้ารหัสที่สอดคล้องกันของ "I" คือ 6211 การเข้ารหัสของ "ใช่" คือ 662F และการเข้ารหัสของ "CM" คือ CM
โปรดทราบว่า Escape () ไม่ถูกต้องสำหรับการเข้ารหัส "+" แต่เรารู้ว่าหากมีช่องว่างบนหน้าเว็บเมื่อส่งแบบฟอร์มมันจะถูกแปลงเป็นอักขระ + เมื่อเซิร์ฟเวอร์ประมวลผลข้อมูลเครื่องหมาย + จะถูกประมวลผลลงในช่องว่าง ดังนั้นระวังเมื่อใช้
encodeuri
การเข้ารหัส URL ทั้งหมดจะใช้รูปแบบ UTF-8 เพื่อส่งออกสตริงที่เข้ารหัส อย่างไรก็ตาม ENCODEURI จะไม่เข้ารหัสอักขระพิเศษบางตัวยกเว้นการเข้ารหัส ASCII เช่น:! - - -
encodeuricomponent ()
แปลงสตริง URI เป็นสตริงรูปแบบหลบหนีในรูปแบบการเข้ารหัส UTF-8 เมื่อเทียบกับ encodeuri, encodeuricomponent จะมีประสิทธิภาพมากขึ้นและจะถูกเข้ารหัสสำหรับสัญลักษณ์ (; /?: @ & = + $, #) ที่ไม่ได้เข้ารหัสใน encodeuri () อย่างไรก็ตาม encodeuricomponent จะเข้ารหัสส่วนประกอบของ URL เป็นรายบุคคลเท่านั้นและจะไม่ถูกใช้เพื่อเข้ารหัส URL ทั้งหมด วิธีการถอดรหัสฟังก์ชั่นการถอดรหัสที่สอดคล้องกัน
แน่นอนเรามักจะใช้ปาร์ตี้ ENCODEURI เพื่อดำเนินการเข้ารหัส การเข้ารหัส JavaScript ที่เรียกว่าและถอดรหัสสองครั้งในพื้นหลังคือการใช้วิธีนี้ มีวิธีแก้ปัญหาสองวิธีในการแก้ปัญหานี้ใน JavaScript: การแปลงรหัสหนึ่งครั้งและวิธีการแปลงรหัสสองวิธี
การแปลงรหัสครั้งเดียว
JavaScript Transcoding:
var url = '/showMobLieqrCode.servlet?name=i am cm'; window.location.href = encodeuri (url);
URL transcoded: http://127.0.0.1:8080/perbank/showmobleqrcode.servlet?name=%E6%88%91%E6%98%AFCM
การประมวลผลแบ็กเอนด์:
ชื่อสตริง = request.getParameter ("ชื่อ"); System.out.println ("พารามิเตอร์ขาเข้าเบื้องหน้า:" + ชื่อ); ชื่อ = ใหม่สตริง (name.getBytes ("ISO-8859-1"), "UTF-8"); System.out.println ("พารามิเตอร์ที่ถอดรหัส:" + ชื่อ);ผลลัพธ์ผลลัพธ์:
พารามิเตอร์ที่เข้ามาในแผนกต้อนรับ: ???????
หลังจากถอดรหัสพารามิเตอร์: ฉันเป็น CM
การแปลงรหัสทุติยภูมิ
จาวาสคริปต์
var url = '/showMobLieqrCode.servlet?name=i am cm'; window.location.href = encodeuri (encodeuri (url));
URL ที่ถูกแปลงรหัส: http://127.0.0.1:8080/perbank/showmobleqrcode.servlet?name=%25E6%2588%2591%25E6%2598%25AFCM
การประมวลผลแบ็กเอนด์:
ชื่อสตริง = request.getParameter ("ชื่อ"); System.out.println ("พารามิเตอร์ที่เข้ามาเบื้องหน้า:" + ชื่อ); name = urldecoder.decode (ชื่อ, "UTF-8"); System.out.println ("พารามิเตอร์ที่ถอดรหัส:" + ชื่อ);ผลลัพธ์ผลลัพธ์:
พารามิเตอร์ขาเข้าด้านหน้า: E68891E698AFCM
หลังจากถอดรหัสพารามิเตอร์: ฉันเป็น CM
กรอง
การใช้ตัวกรองตัวกรอง LZ มีสองประเภทแรกคือการตั้งค่าการเข้ารหัสและที่สองคือการดำเนินการถอดรหัสโดยตรงในตัวกรอง
ตัวกรอง 1
ตัวกรองนี้ตั้งค่ารูปแบบการเข้ารหัสของคำขอโดยตรง
ตัวละครระดับสาธารณะใช้ตัวกรอง {private filterConfig config; การเข้ารหัสสตริง = null; โมฆะสาธารณะทำลาย () {config = null; } โมฆะสาธารณะ dofilter (คำขอ ServletRequest, การตอบสนอง servletResponse, ห่วงโซ่ FilterChain) พ่น IOException, ServleTexception {request.Setcharacterencoding (การเข้ารหัส); chain.dofilter (คำขอ, การตอบกลับ); } public void init (filterConfig config) พ่น servletexception {this.config = config; // รับพารามิเตอร์การกำหนดค่าสตริง str = config.getInitParameter ("การเข้ารหัส"); if (str! = null) {encoding = str; - การกำหนดค่า:
<silter> <m.test.filter.characterencodingFilter-class> <init-param> <init-param> <url-pattern>/*url-pattern> การแมปตัวกรอง>
ตัวกรอง 2
ในวิธีการประมวลผลตัวกรองจะถอดรหัสพารามิเตอร์โดยตรงจากนั้นรีเซ็ตพารามิเตอร์ที่ถอดรหัสไปยังแอตทริบิวต์คำขอ
ตัวละครระดับสาธารณะใช้ตัวกรอง {ตัวกรองที่ได้รับการป้องกัน FilterConfig; การเข้ารหัสสตริง = null; โมฆะสาธารณะทำลาย () {this.filterConfig = null; } / *** เริ่มต้น* / public void init (filterConfig filterConfig) {this.filterConfig = filterConfig; } / *** แปลง INTR ลงในแบบฟอร์มการเข้ารหัสของ UTF -8** @Param Instr ป้อนสตริง* @return UTF - สตริงการเข้ารหัส 8 ของ 8* @throws unsupportencodeNingException* / สตริงส่วนตัว toutf (string instr) โยน unsupportencodexception {string outstr = ""; if (instr! = null) {outstr = new String (strop.getBytes ("ISO-8859-1"), "UTF-8"); } return outstr; } / *** การประมวลผลการกรองภาษาจีนที่อ่านไม่ออก* / โมฆะสาธารณะ dofilter (servletrequest servletrequest, servletresponse servletresponse, chain filterchain) โยน ioexception, servletexception httpservletResponse response = (httpservletResponse) servletResponse; // วิธีการรับคำขอ (1.post หรือ 2.get) และการประมวลผลที่แตกต่างกันจะดำเนินการตามวิธีการร้องขอวิธีการสตริง = request.getMethod (); // 1. สำหรับคำขอที่ส่งในโพสต์ตั้งค่าการเข้ารหัสโดยตรงเป็น UTF-8 ถ้า (method.equalsignorecase ("post")) {ลอง {request.setcharacterencoding ("UTF-8"); } catch (unsupportencodingexception e) {e.printstacktrace (); }} // 2. คำขอที่ส่งใน Get Else {// ออกชุดพารามิเตอร์ที่ส่งโดยไคลเอ็นต์การแจกแจง ParamNames = request.getParameterNames (); // traverse ชุดพารามิเตอร์เพื่อออกชื่อและค่าของแต่ละพารามิเตอร์ในขณะที่ (paramnames.hasmoreElements ()) {ชื่อสตริง = paramNames.nextElement (); // นำค่าสตริงชื่อพารามิเตอร์ [] = request.getParameterValues (ชื่อ) ตั้งค่าสำหรับ (int i = 0; i <value.length; i ++) {ลอง {// วงกลมกลับและโทรแต่ละค่า toutf (ค่า [i]) วิธีการแปลงการเข้ารหัสอักขระของสตริงค่าพารามิเตอร์ vlustr = toutf (ค่า [i]); ค่า [i] = vlustr; } catch (unsupportencodingexception e) {e.printstacktrace (); }} // ซ่อนค่าในรูปแบบของแอตทริบิวต์ใน request request.setAttribute (ชื่อ, ค่า); }}} // ตั้งค่าวิธีการตอบกลับและสนับสนุนชุดอักขระจีนตอบสนองการตอบสนอง SetContentType ("ข้อความ/html; charset = utf-8"); // ดำเนินการต่อเพื่อเรียกใช้ตัวกรองถัดไป หากไม่มีตัวกรองโซ่คำขอ dofilter (คำขอการตอบกลับ); -การกำหนดค่า:
<silter> <m.test.filter.CharacterencodingFilter-class> <filter> <filter>
อื่น
1. SET PAGEENCODING และ ContentType
<%@ page language = "java" contentType = "ข้อความ/html;
charset = utf-8 "pageencoding =" utf-8 "%>
2. ตั้งค่า uriencoding ของ tomcat
โดยค่าเริ่มต้นเซิร์ฟเวอร์ TOMCAT ใช้รูปแบบการเข้ารหัส ISO-8859-1 เพื่อเข้ารหัส URL ที่ร้องขอโดยพารามิเตอร์ URIENCODING ดังนั้นเราจึงต้องเพิ่ม UrienCoding =” UTF-8” ไปยังแท็กของไฟล์ Server.xml ของ TomCat
ข้างต้นเป็นเรื่องเกี่ยวกับบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์สำหรับทุกคนในการเรียนรู้คำถามที่อ่านไม่ออกภาษาจีน Java