如何将用户创建的HTML发送到W3C验证器以进行自动检查,而不会出现跨域错误

How to send user-created HTML to W3C validator for automatic checking—without cross-domain errors?

本文关键字:检查 错误 创建 用户 HTML 验证 W3C      更新时间:2023-09-26

我正在为用户编写一个应用程序,在这个应用程序中,他们将有效的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&标题=视图% 20 w3c验证器% 20 flattr.com&% 20;从框架URL http://validator.w3.org/#validate_by_input。的正在访问的框架设置为"文档"。域名'到'flattr.com',但是请求访问的帧没有。两者都必须设置文档。域的

我将此归因于跨域安全(参见不安全的JavaScript试图使用URL访问框架)

我的问题:是否有一种方法可以将数据发送到验证器,以便我的用户可以检查他们自己的标记?

我认为下面的代码片段可以让你获得同样的效果和用户体验。

它是用jQuery的$.ajax(…)和一些DOMParserdocument.write(…)来编写的,把样式的结果和W3C HTML检查器的UI放入一个新的窗口,看起来你想要的方式。

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检查器
  • 使storyhtml文本成为POST正文
  • 使text/html;charset=utf-8成为POST body的媒体类型(检查器所期望的)
  • 使检查器实际自动检查storyhtml内容
  • 显示检查结果在一个新的窗口,当它第一次打开,在一个步骤(所以你的用户不需要做第二步手动提交检查自己)
  • 用绝对url替换检查器前端CSS+JS的相对url(否则在这个"独立窗口"环境中,CSS不会被应用,脚本也不会运行)
  • newWin.location.hash = "#textarea"需要使检查器显示textarea

指出

  • 有意使用当前的W3C HTML检查器(而不是旧的W3C标记验证器)

  • 故意将要检查的内容作为POST body发送,而不是multipart/form-data);检查器支持multipart/form-data,但使其成为POST体更容易和更好

  • setTimeout textarea位不需要;我只是把它,使结果可见没有滚动(底部的新窗口下方的文本区域);如果你想的话,你当然可以删除它

  • 将新窗口的高度和宽度设置为略大于问题原始代码中的600x600;同样,我这样做只是为了更容易看到;

  • 使用标准DOM操作,可能有更好的jQuery方法/习惯用法(我通常不使用jQuery,所以我可以想象有办法进一步围绕jQuery精简代码)

  • 当然也可以在不使用jQuery的情况下完成——使用标准的Fetch或XHR代替(如果需要的话,我很乐意在这里添加使用Fetch和XHR的例子)

  • 测试,在Edge, Firefox, Chrome &狩猎;但是对于任何使用document.open的代码,Safari用户需要取消设置Preferences> Security> Block弹出窗口