จะส่ง HTML ที่ผู้ใช้สร้างขึ้นไปยังเครื่องมือตรวจสอบ W3C เพื่อตรวจสอบอัตโนมัติโดยไม่มีข้อผิดพลาดข้ามโดเมนได้อย่างไร

ฉันกำลังเขียนแอปพลิเคชันสำหรับผู้ใช้ โดยให้ผู้ใช้ป้อน HTML ที่ถูกต้องลงในช่องข้อความ

ฉันมีปุ่มใน jQuery ซึ่งพยายามโหลดพื้นที่ฟิลด์ข้อความลงในเครื่องมือตรวจสอบ W3C:

$('#inspecthtml').on('click', function() {
             var storyhtml = $('#story').text();
             validatorurl= "http://validator.w3.org/#validate_by_input";
             var newWin = open(validatorurl,'Validator','height=600,width=600');
             newWin.onload = function() {
                 newWin.document.getElementById("fragment").value=storyhtml;
             }           
    });

ฉันได้รับข้อความแสดงข้อผิดพลาดในคอนโซล (โดยใช้ Chrome):

JavaScript ที่ไม่ปลอดภัยพยายามเข้าถึงเฟรมด้วย URL http://api.flattr.com/button/view/?url=http%3A%2F%2Fvalidator.w3.org%2F&title=View%20W3C-Validator%20on%20flattr.com& จากเฟรมที่มี URL http://validator.w3.org/#validate_by_input. เฟรมที่กำลังเข้าถึงตั้งค่า 'document.domain' เป็น 'flattr.com' แต่เฟรมที่ร้องขอการเข้าถึงไม่ได้ ทั้งสองต้องตั้งค่า 'document.domain' เป็นค่าเดียวกันจึงจะอนุญาตการเข้าถึง

ฉันถือว่าสิ่งนี้เป็นการรักษาความปลอดภัยข้ามโดเมน (ดู ความพยายาม JavaScript ที่ไม่ปลอดภัยในการเข้าถึงเฟรม ด้วย URL)

คำถามของฉัน: มีวิธีส่งข้อมูลไปยังเครื่องมือตรวจสอบเพื่อให้ผู้ใช้ของฉันสามารถตรวจสอบมาร์กอัปของตนเองได้หรือไม่


person Sablefoste    schedule 01.01.2013    source แหล่งที่มา
comment
สิ่งนี้ดีกว่าการมีลิงก์ไปยังเครื่องมือตรวจสอบความถูกต้องอย่างไร   -  person Matti Virkkunen    schedule 02.01.2013
comment
คุณเคยดู jsonp หรือไม่?   -  person jchapa    schedule 02.01.2013
comment
@MattiVirkkunen น้อยลงหนึ่งก้าว และฝึกอบรมผู้ใช้น้อยลง หากพวกเขาเห็นเส้นสีเขียวพวกเขาก็รู้ว่ามันดี   -  person Sablefoste    schedule 02.01.2013
comment
@jchapa ไม่ คุณช่วยแนะนำฉันหน่อยได้ไหม?   -  person Sablefoste    schedule 02.01.2013
comment
@Sable: ฉันกลัวที่จะให้ผู้ที่ต้องการการฝึกอบรมให้ใช้เครื่องมือตรวจสอบ W3C เพื่อเขียนโค้ดใด ๆ ตั้งแต่แรก   -  person Matti Virkkunen    schedule 02.01.2013


คำตอบ (1)


ฉันคิดว่าข้อมูลโค้ดด้านล่างจะทำให้คุณได้รับเอฟเฟกต์และประสบการณ์การใช้งานแบบเดียวกันตามที่คุณต้องการ

เขียนโดยใช้ $.ajax(…) ของ jQuery พร้อมด้วย DOMParser และ document.write(…) บางส่วนเพื่อใส่ผลลัพธ์ที่มีสไตล์และ UI ของ W3C HTML Checker ลงในหน้าต่างใหม่ตามที่คุณต้องการ

var validator_baseurl= "https://validator.w3.org/nu/";
var validator_requesturl = validator_baseurl
    + "?showsource=yes&showoutline=yes";
$.ajax({
    url: validator_requesturl,
    type: "POST",
    crossDomain: true,
    data: storyhtml,
    contentType: "text/html;charset=utf-8",
    dataType: "html",
    success: function (response) {
        var results = (new DOMParser()).parseFromString(response, "text/html");
        results.querySelector("link[rel=stylesheet]").href
            = validator_baseurl + "style.css";
        results.querySelector("script").src
            = validator_baseurl + "script.js";
        results.querySelector("form").action
            = validator_requesturl;
        var newWin = window.open("about:blank",
            "Checker results", "height=825,width=700");
        newWin.document.open();
        newWin.document.write(results.documentElement.outerHTML);
        newWin.document.close();
        newWin.location.hash = "#textarea";
        setTimeout(function() {
            newWin.document.querySelector("textarea").rows = "5";
        }, 1000)
    }
});

คำอธิบาย

  • ทำให้คำขอ POST ถูกส่งไปยัง W3C HTML Checker
  • ทำให้ข้อความ storyhtml กลายเป็นเนื้อหา POST
  • ทำให้ text/html;charset=utf-8 เป็นประเภทสื่อของเนื้อหา POST (สิ่งที่ผู้ตรวจสอบคาดหวัง)
  • ทำให้ตัวตรวจสอบตรวจสอบเนื้อหา storyhtml โดยอัตโนมัติ
  • แสดงผลลัพธ์ของตัวตรวจสอบในหน้าต่างใหม่ทันทีที่เปิดครั้งแรกในขั้นตอนเดียว (ดังนั้นผู้ใช้ของคุณไม่จำเป็นต้องทำขั้นตอนที่ 2 เพื่อส่งเพื่อตรวจสอบด้วยตนเอง)
  • แทนที่ URL สัมพัทธ์สำหรับ CSS+JS ส่วนหน้าของตัวตรวจสอบด้วย URL ที่สมบูรณ์ (มิฉะนั้นในบริบท "หน้าต่างสแตนด์อโลน" นี้ CSS จะไม่ถูกนำไปใช้ และสคริปต์จะไม่ทำงาน)
  • จำเป็นต้องใช้ newWin.location.hash = "#textarea" เพื่อให้ตัวตรวจสอบแสดงพื้นที่ข้อความ

หมายเหตุ

  • จงใจใช้ ตัวตรวจสอบ HTML W3C ปัจจุบันโดยเจตนา (ไม่ใช่เครื่องมือตรวจสอบมาร์กอัป W3C เดิม)

  • จงใจส่งเนื้อหาที่จะตรวจสอบเป็นเนื้อหา POST ไม่ใช่ multipart/form-data) ตัวตรวจสอบรองรับ multipart/form-data แต่การทำให้เป็นเนื้อหา POST นั้นง่ายกว่าและดีกว่า

  • ไม่จำเป็นต้องใช้ setTimeout textarea บิต ฉันแค่ใส่มันเพื่อทำให้มองเห็นผลลัพธ์ได้โดยไม่ต้องเลื่อน (ส่วนล่างของหน้าต่างใหม่ใต้พื้นที่ข้อความ) แน่นอนคุณสามารถลบมันออกได้หากต้องการ

  • ตั้งค่าความสูงและความกว้างของหน้าต่างใหม่ให้ใหญ่กว่าขนาด 600x600 เล็กน้อยในโค้ดต้นฉบับของคำถาม อีกครั้ง ฉันแค่ทำอย่างนั้นเพื่อให้มองเห็นสิ่งต่างๆ ได้ง่ายขึ้น เปลี่ยนสิ่งที่คุณต้องการ

  • ใช้ตัวเลือก DOM มาตรฐานที่อาจมีวิธี/สำนวน jQuery ที่ดีกว่า (ปกติฉันจะไม่ใช้ jQuery ดังนั้นฉันจึงจินตนาการได้ว่ามีวิธีปรับปรุงโค้ดใน JQuery เพิ่มเติม)

  • แน่นอนว่าสามารถทำได้โดยไม่ต้องใช้ jQuery เลย โดยใช้มาตรฐาน Fetch หรือ XHR แทน (และฉันยินดีที่จะเพิ่มตัวอย่างที่นี่ซึ่งใช้ Fetch และ XHR หากต้องการ)

  • ทดสอบและทำงานตามที่คาดไว้ใน Edge, Firefox, Chrome & Safari; แต่เช่นเดียวกับรหัสอื่นๆ ที่ใช้ document.open ผู้ใช้ Safari จะต้องยกเลิกการตั้งค่า ค่ากำหนด > ความปลอดภัย > บล็อกหน้าต่างป๊อปอัป

person sideshowbarker    schedule 13.09.2015
comment
ดูเหมือนคำตอบที่ดีและสมเหตุสมผล ฉันจะให้ +1 แก่คุณสำหรับการวิเคราะห์โดยละเอียด อย่างไรก็ตาม ยังต้องดำเนินการอีกเล็กน้อย ดังนั้นฉันจึงต้องใช้เวลาในการประเมิน เมื่อฉันทำ (สมมติว่าได้ผล) ฉันจะให้เครื่องหมายถูกยอมรับ - person Sablefoste; 14.09.2015