W3C Html 我的 textArea 中的验证器

W3C Html Validator inside my textArea

我正在开发一个网站,用户可以在其中的文本区域中编写描述。此描述可能类似于包含所有 html 标签 (<b></b><a href=''/> etc...) 的 html 内容。

有时,用户会犯错误(比如写 <a href='"/> 或不关闭标签),当在我的网站上呈现描述时,它会破坏所有页面。

我正在寻找 javascript 库或其他工具来验证文本区域内容。类似于 jsfiddle 的东西,但是在我的网站上。

谢谢

更新

为了使用我的应用程序,我简化了流程。这是代码

HTML

<div>
   <div class="row">
    <textarea id="idTextArea" style="width:300px; height:100px;"></textarea>
    <button class="btn btn-default" id="idButton">Validate</button>
   </div>
</div>

Javascript

<script type="text/javascript">
$("#idButton").click(function () {
    var textToTest = "<!DOCTYPE html><html><head><title>Test</title></head><body>" + $("#idTextArea").val() + "</body></html>";

    // emulate form post
    var formData = new FormData();
    formData.append('out', 'json');
    formData.append('content', textToTest);

    // make ajax call
    $.ajax({
        url: "http://html5.validator.nu/",
        data: formData,
        dataType: "json",
        type: "POST",
        processData: false,
        contentType: false,
        success: function (data) {
            var text = "";
            for(var i = 0; i < data.messages.length; i++)
            {
                var extract = data.messages[i].extract;
                var firstColumn = data.messages[i].firstColumn;
                var hiliteStart = data.messages[i].hiliteStart;
                var hiliteLength = data.messages[i].hiliteLength;
                var lastColumn = data.messages[i].lastColumn;
                var lastLine = data.messages[i].lastLine;
                var type = data.messages[i].type;
                var message = data.messages[i].message;

                text += "Type : " + type;
                text += "Message : " + message;

            }
            if (text.length > 0) {
                alert(text);
            }
        },
        error: function () {
            alert(arguments);
        }
    });
})

这可能需要一些修补,但现在就可以了。使用 W3C validator API

当用户在文本区域中写描述时,使用ajax将此内容发送到后端脚本。在后端脚本中,将文本区域内容保存到可公开访问的 .html 文件(比如 textarea.html)。

然后,在保存文件后的同一脚本中,使用已保存内容的 .html 文件的 URL 向 W3C Validator API 发送 CURL 请求:

$filepath        = '/mycontent/textarea.html';
$current_content = file_get_contents($filepath);//if you need the old content for some reason
$new_content     = $_GET['textarea_content'];

file_put_contents($new_content, $filepath);

// now use the validator
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://validator.w3.org/check?uri=http://www.myproject.com/mycontent/textarea.html/&output=json");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$output = json_decode(curl_exec($ch), 1);

curl_close($ch);

然后解析JSON(即$output)看是否有错误。我亲自尝试过 API 并且它确实 return 一个 JSON 响应,其中包含在您的查询参数的 URI 中发现的所有错误。

如果你只想检查它是否有效则拒绝它(不是自动修复它或执行某种错误突出显示)那么一种合理有效的检查方法是使用一些 xml 解析库来解析它的一个小写副本。如果解析失败,那么它很可能是无效的 html.

也许并非所有有效的 html5 字符串都能通过测试,但由于通过了测试,可以确保使用更礼貌的方式来编写它。

NodeJS 中的示例使用 xml2json:

#!/usr/bin/env node

// REQUIRES: npm install xml2json
var x2j = require("xml2json").toJson;


function checkHtml(src) {
    try {
        x2j("<data>"+String(src).toLowerCase()+"</data>");
    } catch (err) {
        return false;
    };
    return true;
};

[   
    "<b>Hello World!!</B>",
    "<b>Hello World!!</ B>",
].map(function(html){
    console.log (html, checkHtml(html));
});

// Output:
// -------
// <b>Hello World!!</B> true
// <b>Hello World!!</ B> false

虽然您说过要在您的网站上执行任务,但我不确定您是否会觉得这种方法不合适。基本上,您可以在您的站点上使用一个表单,然后将其提交给 API.

在这里,我只使用了普通表单提交(即,不是 ajax),因此用户最终会在显示结果的验证器站点结束。但是,如果您通过 ajax 提交并明确要求 JSON 输出,您也可以显示结果。

我使用了以下几个 link: https://github.com/validator/validator/wiki/Service%3A-Input%3A-textarea https://github.com/validator/validator/wiki/Service%3A-Common-parameters

并产生了这个:

<form id='mForm' method='post' action='http://validator.w3.org/nu/' enctype='multipart/form-data'>
    <button type='submit'>Submit</button>
    <textarea id='checkMe' name='content'></textarea>
</form>

从第一个link开始: 您必须确保内容字段是提交中的最后一个字段。

但是,这并不是很令人满意。当然我们可以做得更好? 所以我继续阅读并意识到实施 ajax 解决方案并没有太多工作,所以我快速地拼凑了一个 n 讨厌的解决方案。您可以选择要使用的验证器,然后将响应返回为 JSON,我只是将其填充到 div 中。您应该解析 JSON 并创建结构化 error/success 消息。

这是一个在页面上有效的现场演示:

function byId(id){return document.getElementById(id)}

function ajaxPostForm(url, formElem, onSuccess, onError)
{
 var ajax = new XMLHttpRequest();
 ajax.onreadystatechange = function(){if (this.readyState==4 && this.status==200)onSuccess(this);}
 ajax.onerror = function(){error.log("AJAX request failed to: "+url);onError(this);}
 ajax.open("POST", url, true);
 var formData = new FormData(formElem);
 ajax.send( formData );
}


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
window.addEventListener('load', onDocLoaded, false);

function onDocLoaded(evt)
{
 byId('goBtn').addEventListener('click', onGoBtnClicked);
}

function onGoBtnClicked(evt)
{
 ajaxPostForm('http://validator.w3.org/nu/', byId('mForm'), onAjaxOk, onAjaxFail);
 
 function onAjaxOk(ajax)
 {
  byId('ajaxResult').textContent = ajax.response;
 }
 
 function onAjaxFail(ajax)
 {
  alert("bugger. No idea what happened here - I should've bother error checking :p..");
 }
}
textarea
{
 width: 500px;
 height: 400px;
}
 <h3>Enter code to be validated by w3c</h3>
 <form id='mForm' method='post' action='http://validator.w3.org/nu/' enctype='multipart/form-data'>
  <input type='hidden' name='out' value='json'/>
  <textarea id='checkMe' name='content'></textarea><br>
  <select name='parser'>
   <option value='none'>Select Parser</option>
   <option value='xml'>XML parser, will not load external entities</option>
   <option value='xmldtd'>XML parser, will load external entities</option>
   <option value='html'>HTML parser, configuration is based on doctype.</option>
   <option value='html5'>HTML parser in the HTML5 mode.</option>
   <option value='html4'>HTML parser in the HTML4 strict mode.</option>
   <option value='html4tr'>HTML parser in the HTML4 transitional mode.</option>
  </select>
 </form>
 <button id='goBtn'>Submit</button>
 <hr>
 <div id='ajaxResult'></div>