3

Edit 1

This is not about the browser. This happens if I'm not logged in. When I logged in, it works perfectly. Sorry for the rush.

I know it strange and doesn't make any sense also hard to explain.

As the title said browser causes this problem but I'm not sure about it.

So I have an image service that reads some data from somewhere and creates images by the read data. Then it does a few things and returns the images in base64 format so I can use the images in my web site. This process begins as soon as I open a page on my web site.

The problem is that if I open the page on Safari it works properly but today I tried to open the page on Chrome and images didn't load. So I checked the images and saw that there's no data attribute at the beginning of the data URI.

Let me explain with an example;

Here's my code while creating the HTML template

  presets += `<div class="icon"> <img src="data:image/png;base64,${icon}"></div>`
  presets += `<p class="name">${name}</p>`
  presets += `<div class="image"> <img src="data:image/png;base64,${image}"/></div>`

I'm doing a few things and then returning this data and on postman and safari I'm getting this result:

<div class="icon"> <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA{ ... }"></div>

So this is fine. Nothing's wrong with that.

But when I opened the page on Chrome or Opera I'm getting this;

<div class="icon"> <img src="image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA{ ... }"></div>

See? No data attribute. I'm inserting a post in Wordpress and this is the content of the post. Why is that happening? I hope I've explained my self clearly.

Edit 2

This is the function that I used to insert a post

function programmatically_create_post($title, $content, $slug)
{

    // Setup the author,
    $author_id = 4;

    // If the page doesn't already exist, then create it
    if (!the_slug_exists($slug)) {

            // Set the post ID so that we know the post was created successfully
            wp_insert_post( 
                    array(  
                            'post_title'            =>      $title,
                            'post_content'          =>      $content,
                            'comment_status'        =>      'closed',
                            'ping_status'           =>      'closed',
                            'post_author'           =>      $author_id,
                            'post_name'             =>      $slug,  
                            'post_status'           =>      'publish',
                            'post_type'             =>      'post', 
                            'page_template'         =>      'dynamic-post.php',
                            'post_category'         =>      array(1,60)
                         )
            );
            // Redirect user to the post after the post created
            wp_redirect(get_site_url() . '/blog/' . $slug);
            exit();
            // Otherwise, we'll stop
    } else {
            return;
    } // end if

} // end programmatically_create_post
tpbafk
  • 501
  • 5
  • 26
  • *I'm inserting a post in Wordpress and this is the content of the post.* - Inserting how? Using the CMS? Using the API? Directly into the DB? Clearly something is stripping that content, understanding the process you are doing step by step and seeing more of your code would be useful... – naththedeveloper Nov 28 '19 at 14:40
  • Also when is it stripped out? During display or during saving the new post? i.e. does the `data:` prefix appear in your database? – naththedeveloper Nov 28 '19 at 14:42
  • No, it doesn't appear in my DB. I'm using `wp_insert_post` function to insert. It stripped out during saving the new post – tpbafk Nov 28 '19 at 14:44
  • Also, I think it's about Wordpress's security thing. So I've added below function into my functions.php but no luck `if ( ! function_exists( 'extend_allowed_html_tags' ) ) { function extend_allowed_html_tags() { global $allowedposttags; $allowedposttags['img']['data'] = true; } } add_action( 'init', 'extend_allowed_html_tags'); ` – tpbafk Nov 28 '19 at 14:47
  • @naththedeveloper I updated my question. I tried a few things like allowing HTML tags but didn't work at all. – tpbafk Nov 28 '19 at 15:44
  • I think I got it, took me a bit of digging, added an answer, please give it a go, seemed to work in my testing. – naththedeveloper Nov 28 '19 at 15:46

1 Answers1

12

Well, this was a nightmare to find, but I think I've resolved it after digging through the WordPress code which hooks in through wp_insert_post. Please add this to your functions.php file and check it works:

add_filter('kses_allowed_protocols', function ($protocols) {
    $protocols[] = 'data';

    return $protocols;
});

Essentially internally in WordPress there's a filter which checks the protocol of any URL's in the content and strips any which it doesn't like. By default the supported list doesn't support the data protocol. The above function just adds it to the list of supported protocols.

This filter does not run if you're an administrator, which is probably why you're seeing this issue only when logged out.

naththedeveloper
  • 4,503
  • 6
  • 36
  • 44