简体   繁体   中英

W3C Html Validator inside my textArea

I'm developing a website in which the user can write a description in a textarea. This description could be like an html content with all the html tags ( <b></b><a href=''/> etc... ).

Sometimes, user make mistakes (like writing <a href='"/> or don't close tags) and when the description is render in my website, it breaks all the page.

I'm looking for a javascript library or an other tool in order to validate the textarea content. Something similar to jsfiddle, but in my website.

Thanks

UPDATE

In order to work with my app, I simplify the process. Here is the code

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);
        }
    });
})

This may work with some tinkering but here goes. Use the W3C validator API

When user writes description in the textarea, use ajax to send this content to a backend script. In the backend script, save the textarea content to a .html file (say textarea.html) that is publicly accessible.

Then, in same script after file has been saved, send a CURL request to the W3C Validator API , using the URL of your saved content's .html file:

$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);

Then parse the JSON (ie, $output) to see if there are errors. I have personally tried this API and it does return a JSON response containing all of the errors found in your query parameter's URI.

If you only want to check if it is valid to reject it if not (not automatically fix it or perform some kind of error highlighting) then a reasonably efficient way to check it would be to use some xml parsing library to parse a lowercased copy of it. If parsing fails, then it's much probably invalid html.

Maybe not all valid html5 strings would pass the test, but sure use could write it in more polite way due to pass the test.

Example in NodeJS using 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

While you've said that you want the task performed in side your website, I'm not sure if you'll find this approach unsuitable. Basically, you can use a form on your site which is then submitted to the API.

Here, I've just used a normal form submit (ie, not ajax) and so the user ends up at the validator's site with the results displayed. If however, you were to submit via ajax and explicitly ask for JSON output, you could display the results too.

I used the following couple of links: https://github.com/validator/validator/wiki/Service%3A-Input%3A-textarea https://github.com/validator/validator/wiki/Service%3A-Common-parameters

and produced this:

<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>

From the first link: You must ensure that the content field is the last field in the submission.

But, that's just not very satisfying. Surely we can do better? So I kept reading and realized it wasn't much work to implement an ajax solution, so I threw a quick n nasty one together. You can pick the validator to be used and you get the response back as JSON, which I simply stuff into a div. You should parse the JSON and create structured error/success messages.

Here's a live demo that works right here on the page:

 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> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM