ไม่มีวิธีใดที่จะทำให้แตกต่างจากเว็บเบราว์เซอร์ใหม่ล่าสุด
ข้อกำหนด W3C:
ขั้นตอนด้านล่างอธิบายถึงสิ่งที่ตัวแทนผู้ใช้ต้องทำสำหรับคำขอข้ามแหล่งที่มาง่ายๆ :
ทำตามขั้นตอนการร้องขอและปฏิบัติตามกฎการร้องขอด้านล่างขณะทำการร้องขอ
หากไม่ได้ตั้งค่าสถานะการเปลี่ยนเส้นทางด้วยตนเองและการตอบกลับมีรหัสสถานะ HTTP 301, 302, 303, 307 หรือ 308 ให้
ใช้ขั้นตอนการเปลี่ยนเส้นทาง
หากผู้ใช้ยกเลิกการร้องขอ
ใช้ขั้นตอนการยกเลิก
หากมีข้อผิดพลาดของเครือข่าย
ในกรณีที่มีข้อผิดพลาด DNS, TLS ความล้มเหลวของการเจรจาต่อรองหรือชนิดอื่น ๆ ของข้อผิดพลาดของเครือข่ายการใช้ขั้นตอนข้อผิดพลาดของเครือข่าย อย่าร้องขอการโต้ตอบกับผู้ใช้ปลายทางใด ๆ
หมายเหตุ: ไม่รวมการตอบกลับ HTTP ที่ระบุข้อผิดพลาดบางประเภทเช่นรหัสสถานะ HTTP 410
มิฉะนั้นให้
ทำการตรวจสอบการแชร์ทรัพยากร หากส่งคืนล้มเหลวให้ใช้ขั้นตอนข้อผิดพลาดของเครือข่าย มิฉะนั้นหากส่งคืนค่าผ่านให้ยุติอัลกอริทึมนี้และตั้งค่าสถานะคำขอข้ามต้นทางเป็นสำเร็จ ห้ามยุติคำขอจริง
ดังที่คุณอ่านข้อผิดพลาดของเครือข่ายไม่รวมการตอบสนอง HTTP ที่มีข้อผิดพลาดนั่นคือเหตุผลที่คุณจะได้รับ 0 เป็นรหัสสถานะเสมอและ "" เป็นข้อผิดพลาด
แหล่ง
หมายเหตุ : ตัวอย่างต่อไปนี้สร้างขึ้นโดยใช้ Google Chrome เวอร์ชัน 43.0.2357.130 และเทียบกับสภาพแวดล้อมที่ฉันสร้างขึ้นเพื่อเลียนแบบ OP รหัสสำหรับการตั้งค่าจะอยู่ที่ด้านล่างของคำตอบ
ฉันแม้ว่าวิธีการในการแก้ไขปัญหานี้จะเป็นการร้องขอรองผ่าน HTTP แทน HTTPS เป็นคำตอบนี้แต่ฉันจำได้ว่าเป็นไปไม่ได้เนื่องจากเบราว์เซอร์เวอร์ชันใหม่บล็อกเนื้อหาผสม
นั่นหมายความว่าเว็บเบราว์เซอร์จะไม่อนุญาตการร้องขอผ่าน HTTP หากคุณใช้ HTTPS หรือในทางกลับกัน
เป็นเช่นนี้มาตั้งแต่ไม่กี่ปีที่แล้ว แต่เว็บเบราว์เซอร์รุ่นเก่าเช่น Mozilla Firefox ซึ่งอยู่ด้านล่างเวอร์ชัน 23 อนุญาต
หลักฐานเกี่ยวกับเรื่องนี้:
การร้องขอ HTTP จาก HTTPS ใช้คอนโซล Web Broser
var request = new XMLHttpRequest();
request.open('GET', "http://localhost:8001", true);
request.onload = function () {
console.log(request.responseText);
};
request.onerror = function () {
console.log(request.responseText);
};
request.send();
จะส่งผลให้เกิดข้อผิดพลาดต่อไปนี้:
เนื้อหาผสม: หน้าใน ' https: // localhost: 8000 / ' ถูกโหลดผ่าน HTTPS แต่ขอจุดสิ้นสุด XMLHttpRequest ที่ไม่ปลอดภัย ' http: // localhost: 8001 / ' คำขอนี้ถูกบล็อก เนื้อหาจะต้องแสดงผ่าน HTTPS
ข้อผิดพลาดเดียวกันนี้จะปรากฏในคอนโซลของเบราว์เซอร์หากคุณพยายามทำสิ่งนี้ด้วยวิธีอื่นเช่นการเพิ่ม Iframe
<iframe src="http://localhost:8001"></iframe>
การใช้การเชื่อมต่อซ็อกเก็ตก็โพสต์เป็นคำตอบฉันค่อนข้างมั่นใจว่าผลลัพธ์จะเหมือนกัน / คล้ายกัน แต่ฉันได้ลองใช้แล้ว
การพยายามเปิดการเชื่อมต่อซ็อกเก็ตจาก Web Broswer โดยใช้ HTTPS ไปยังปลายทางของซ็อกเก็ตที่ไม่ปลอดภัยจะสิ้นสุดลงด้วยข้อผิดพลาดเกี่ยวกับเนื้อหาผสมกัน
new WebSocket("ws://localhost:8001", "protocolOne");
1) เนื้อหาผสม: หน้าเว็บที่ ' https: // localhost: 8000 / ' ถูกโหลดผ่าน HTTPS แต่พยายามเชื่อมต่อกับปลายทาง WebSocket ที่ไม่ปลอดภัย 'ws: // localhost: 8001 /' คำขอนี้ถูกบล็อก จุดสิ้นสุดนี้ต้องพร้อมใช้งานบน WSS
2) Uncaught DOMException: ล้มเหลวในการสร้าง 'WebSocket': การเชื่อมต่อ WebSocket ที่ไม่ปลอดภัยอาจไม่ได้เริ่มต้นจากหน้าที่โหลดผ่าน HTTPS
จากนั้นฉันได้ลองเชื่อมต่อกับปลายทาง wss ด้วยดูว่าฉันสามารถอ่านข้อมูลบางอย่างเกี่ยวกับข้อผิดพลาดในการเชื่อมต่อเครือข่ายได้หรือไม่:
var exampleSocket = new WebSocket("wss://localhost:8001", "protocolOne");
exampleSocket.onerror = function(e) {
console.log(e);
}
การเรียกใช้ข้อมูลโค้ดด้านบนโดยปิดเซิร์ฟเวอร์ผลลัพธ์ใน:
การเชื่อมต่อ WebSocket ไปยัง 'wss: // localhost: 8001 /' ล้มเหลว: เกิดข้อผิดพลาดในการสร้างการเชื่อมต่อ: net :: ERR_CONNECTION_REFUSED
การดำเนินการตัวอย่างด้านบนโดยเปิดเซิร์ฟเวอร์
การเชื่อมต่อ WebSocket กับ 'wss: // localhost: 8001 /' ล้มเหลว: การจับมือเปิด WebSocket ถูกยกเลิก
แต่อีกครั้งข้อผิดพลาดที่เอาต์พุต "ฟังก์ชัน onerror" ไปยังคอนโซลไม่มีเคล็ดลับใด ๆ ที่จะแยกความแตกต่างของข้อผิดพลาดอื่น ๆ
การใช้พร็อกซีตามคำตอบนี้สามารถใช้ได้ แต่เฉพาะในกรณีที่เซิร์ฟเวอร์ "เป้าหมาย" มีการเข้าถึงแบบสาธารณะ
นี่ไม่ใช่กรณีนี้ดังนั้นการพยายามใช้พร็อกซีในสถานการณ์นี้จะทำให้เราประสบปัญหาเดียวกัน
โค้ดสำหรับสร้าง Node.js เซิร์ฟเวอร์ HTTPS :
ฉันได้สร้างเซิร์ฟเวอร์ Nodejs HTTPS สองตัวซึ่งใช้ใบรับรองที่ลงนามด้วยตนเอง:
targetServer.js:
var https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync('./certs2/key.pem'),
cert: fs.readFileSync('./certs2/key-cert.pem')
};
https.createServer(options, function (req, res) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
res.writeHead(200);
res.end("hello world\n");
}).listen(8001);
applicationServer.js:
var https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync('./certs/key.pem'),
cert: fs.readFileSync('./certs/key-cert.pem')
};
https.createServer(options, function (req, res) {
res.writeHead(200);
res.end("hello world\n");
}).listen(8000);
เพื่อให้ใช้งานได้คุณต้องติดตั้ง Nodejs จำเป็นต้องสร้างใบรับรองที่แยกกันสำหรับแต่ละเซิร์ฟเวอร์และจัดเก็บไว้ในโฟลเดอร์ certs และ certs2 ตามนั้น
ในการเรียกใช้เพียงแค่ดำเนินการnode applicationServer.js
และnode targetServer.js
ในเทอร์มินัล (ตัวอย่างอูบุนตู)