1

I'm trying to send the following content through an AJAX request, I need to store the html content inside a database column.

What I did so far is try to escape the html before send it to AJAX:

let escapedHtml = escapeHtml(content); // content contains the html above (pastebin)
let campaign.content = escapedHtml;
let postData = { campaign: JSON.stringify(campaign) };
let postUrl = 'some url';

$.post(postUrl, postData, function (response) {
   console.log('Yeah, we did it!');
}, 'json').fail(function(){
   console.log('Something bad happened');
});

I've defined a custom function for escaping:

function escapeHtml(string) {
    var entityMap = {
        '&': '&',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        "'": '&#39;',
        '/': '&#x2F;',
        '`': '&#x60;',
        '=': '&#x3D;'
    };

    return String(string).replace(/[&<>"'`=\/]/g, function (s) {
        return entityMap[s];
    });
}

the AJAX request send the content to the Codeigniter controller, which I handle in the following way:

public function ajax_save_campaign()
{
    try
    { 
        $campaign = json_decode($this->input->post('campaign'), TRUE);
        $this->load->model('newsletter_model');
        $campaignId = $this->newsletter_model->add_campaign($campaign);

        $this->output
            ->set_content_type('application/json')
            ->set_output(json_encode([
                'status' => AJAX_SUCCESS,
                'id' => $campaignId
            ]));
    }
    catch(Exception $exc)
    {
        $this->output
            ->set_content_type('application/json')
            ->set_output(json_encode([
                'exceptions' => [exceptionToJavascript($exc)]
            ]));
    }
}

the problem's that if I dump the variable $campaign['content'] I doesn't get the correct html but this which is completely different. So how can I bring back the original html structure from php when the AJAX request is finished?

Thanks.

UPDATE

I cannot send raw html 'cause this will broke the $campaign variable which contains other properties too, eg (html not escaped as did above with escapeHtml):

$campaign = json_decode($this->input->post('campaign'), TRUE);
var_dump($campaign);

the variable $campaign is actually NULL

instead this $this->input->post('campaign') contains the following:

"{"campaign_name":"hello world","sender_title":"test","reply_email":"hello@uxdes54.com","subject":"test","launch_date":1593426034,"groups":"1","templates":"1","content":"<p>Lethe Newsletter Verification</p>\n\n<p> </p>\n\n<p>&lt;!-- page content --&gt;</p>\n\n<div id=\ xss=removed>\n<h3>{ORGANIZATION_NAME}<br>\n<small>E-Mail Verification</small></h3>\n\n<hr>\n<p>Hello {SUBSCRIBER_NAME},</p>\n\n<p>Welcome to {ORGANIZATION_NAME}! Please take a second to confirm <span xss=removed>{SUBSCRIBER_MAIL}</span> as your email address by clicking this link:</p>\n\n<p><strong>{VERIFY_LINK[Click Here!]}</strong></p>\n\n<p>Once you do, you will be able to opt-in to notifications of activity and access other features that require a valid email address.</p>\n\n<p>Thank You!</p>\n\n<hr>\n<div xss=removed><small>{company_name}<br>\n{company_phone_1} - {company_phone_2} </small></div>\n</div>\n\n<div id=\ xss=removed><small>{LETHE_SAVE_TREE}</small></div>\n\n<p>&lt;!-- page content --&gt;</p>\n\n<p> </p>\n"}"
  • 1
    There's no need to escape the HTML if you're just sending it from JS to PHP to be stored in a database. The only escaping you need to do is for SQL injections, but CI's db-class will already handle that for you. Just send and store it "as is". If you later want to output the HTML as code, without the browser render it as HTML, then you need to escape the HTML. – M. Eriksson Jun 29 '20 at 10:09
  • @MagnusEriksson if I not escape content the variable `$campaign` is completely broken, so I cannot access to other properties of that variable – the_only_one Jun 29 '20 at 10:14
  • I removed my comment about JSON since I missed that it was an object you passed and not just the content. But the html still doesn't need to be escaped. If it fails for you, then you should let us know what happens. – M. Eriksson Jun 29 '20 at 10:17
  • @MagnusEriksson please, check my update – the_only_one Jun 29 '20 at 10:25

1 Answers1

2

As Magnus Eriksson stated in a comment, you should just send the raw HTML code via ajax to your PHP controller and insert it into your database.

The content you get by dumping is exactly what you are trying to get - the escaped string. In your PHP there's no function (at least I can't see it) that is un-escaping what you escaped on JS side.

You shouldn't get any problem sending the complete HTML string through ajax.

EDIT: Why are you sending the data as JSON and not the object itself like so?

$.ajax({
 type: 'POST',
 url: post_url,
 data: {
  campaign: campaign
 },
 success: function(msg) {
  console.log(msg)
 }
});
  • @the_only_one - HTML only has a special meaning for the browser when it renders the page. In a request, in PHP or in a database, it's just a string. If it contains HTML or not is irrelevant. So if something gets "broken" when you post it "as is", you need to show us what actually happens and what "broken" means. – M. Eriksson Jun 29 '20 at 10:20
  • What is the data you are getting on PHP side without escaping? Have you tried checking the developer tools for the POST data? – renegade999 Jun 29 '20 at 10:20
  • I would say the forward slashes are a problem (since you don't have any quotation marks) as noted here: https://stackoverflow.com/questions/22551586/write-html-string-in-json On another note: Why are you sending a JSON Object and not just the Object itself? Side note: A helping tool for json data: http://json.parser.online.fr/ – renegade999 Jun 29 '20 at 10:36
  • @renegade999 thanks, seems that removing the json all works as expected and actually the slashes broken up the structure, thanks again – the_only_one Jun 29 '20 at 10:52