我正在为用户编写一个应用程序,在这个应用程序中,他们将有效的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(…)
和一些DOMParser
和document.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弹出窗口