1

我正在为用户编写一个应用程序,他们在其中将有效的 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”设置为相同的值才能允许访问。

我将此归因于跨域安全性(请参阅Unsafe JavaScript attempt to access frame with URL

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

4

1 回答 1

1

我认为下面的代码片段会让您获得与您所追求的相同的效果和用户体验。

它是使用 jQuery 编写的$.ajax(…)DOMParserdocument.write(…)以您想要的方式将 W3C HTML Checker 的样式化结果和 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-8POST 主体的媒体类型(检查器所期望的)
  • 使检查器实际storyhtml自动检查内容
  • 在第一次打开时在一个新窗口中显示检查器结果,一步(因此您的用户无需执行第二步手动提交它以进行检查)
  • 用绝对 URL 替换检查器前端 CSS+JS 的相对 URL(否则在这个“独立窗口”上下文中,CSS 不会被应用,脚本也不会运行)
  • newWin.location.hash = "#textarea"需要使检查器显示文本区域

笔记

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

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

  • setTimeout textarea位不是必需的;我只是把它放在不滚动的情况下使结果可见(文本区域下方新窗口的底部);如果你愿意,你当然可以删除它

  • 将新窗口的高度和宽度设置为比问题原始代码中的 600x600 大一点;再一次,我这样做只是为了让事情更容易看到;随心所欲地改变它们

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

  • 当然也可以完全不使用 jQuery 来完成——使用标准的Fetch或 XHR(如果需要,我很乐意在此处添加使用 Fetch 和 XHR 的示例)

  • tested & works as expected in Edge, Firefox, Chrome & Safari; but as with any code that uses document.open, Safari users need to unset Preferences > Security > Block pop-up windows

于 2015-09-13T09:12:44.990 回答