0

This code attempts to replace image URLs with a Base 64 data string.

I can't get the src attributes to update to base64String. It's unclear if the problem stems from the axios promise, or setAttribute.

const dom = new JSDOM(body, { includeNodeLocations: true, QuerySelector: true, FetchExternalResources: true })
const document = dom.window.document
const imageElements = document.querySelectorAll('img')
imageElements.forEach(async imageElement => {
  const src = imageElement.getAttribute('src')
  axios
    .get(src, { responseType: 'arraybuffer' })
    .then(image => {
      const raw = Buffer.from(image.data).toString('base64')
      const base64String = 'data:' + image.headers['content-type'] + ';base64,' + raw
      imageElement.setAttribute('src', base64String)
    })
    .catch(error => {
      rejects(error)
    })
})
const article = new Readability(document).parse()
const content = sanitizeHtml(article.content, {
  allowedTags: ['h1', 'p' 'a', 'img'],
  allowedAttributes: { img: ['src'] },
})
console.log(content)
// Expect images to be replaced with data string. Original image urls remain as src attributed.
Sebastien
  • 2,607
  • 9
  • 30
  • 40
  • That was a copying error. The problem is that `imageElement.setAttribute('src', base64String)` has no effect no matter what attribute I set. – Sebastien Mar 13 '21 at 08:27
  • What do you mean by "no effect"? What are you looking for that doesn't happen? Or what are you looking at that isn't what you expect? If I run that code locally with a `body` string with an image in it, and look at `imageElement.src` after the `setAttribute`, I see the `data:` URI. – T.J. Crowder Mar 13 '21 at 08:36
  • Could it be that you're looking at the image elements in code immediately following the `forEach` loop above? If so, the problem is that the asynchronous processes the `forEach` loop starts aren't finished yet; see the answers to [this question](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron). – T.J. Crowder Mar 13 '21 at 08:40
  • `base64String` gets generated correctly but `imageElement.setAttribute('src', 'new attribute')` has no effect on the outputed html. It doesn't set the attribute and original image urls remain in the code. – Sebastien Mar 13 '21 at 08:41
  • As I said above, it does if I run that code locally. I think you're [looking too soon](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron). – T.J. Crowder Mar 13 '21 at 08:42
  • If I'm right, this is how you fix it (but see the answers linked above for why): https://pastebin.com/fMNDegJH – T.J. Crowder Mar 13 '21 at 08:44
  • I'll try that. I updated the original post with the full code and where I'm 'looking' – Sebastien Mar 13 '21 at 08:53
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/229853/discussion-between-sebastien-and-t-j-crowder). – Sebastien Mar 13 '21 at 08:58
  • 1
    Yes, that's the problem. You're doing the next part too soon. You need to wait for the asynchronous `axios.get` calls to finish. – T.J. Crowder Mar 13 '21 at 08:59

0 Answers0