I am trying to convert an image img/tab_25/05/38/37/bl1005194/chapter_1/1-1728176695-o.webp
from a webview to base64.
The issue is that the image is protected So I am unable to fetch the image on the serverside.
So I thought about injecting the fetching and converting code to the webview, I thought that as it is from the same orgin I wont get an issue downloading it and converting it to base64.
Here is that code I am using
const getImage = async function (img) {
let src = img.getAttribute("src")
return new Promise(
async (onSuccess, onError) => {
try {
const response = await fetch(src, {
mode: 'no-cors',
referer:"https://chapmanganato.to/",
accept: "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8",
"accept-encoding":"gzip, deflate, br, zstd",
"user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
});
const blob = await response.blob();
const reader = new FileReader();
reader.onerror = function (e) {
console.error(e);
alert(e)
onSuccess("");
}
reader.onload = function () {
if (reader.result)
onSuccess("data:image/jpg;base64,"+reader.result.toString().split(",")[1]);
else onSuccess("");
};
reader.readAsDataURL(blob);
} catch (e) {
console.error(e);
alert(e)
onSuccess("");
}
}
);
}
const getImages = async function () {
try{
let imgArray = [];
let imgs = [...document.querySelectorAll("${parser?.selector}")];
for (let img of imgs) {
let src = await getImage(img);
if (src && src.length>10)
imgArray.push(src)
}
var payload = {
name: "images",
url: "${currentUrl}",
data: imgArray
};
window.ReactNativeWebView.postMessage(JSON.stringify(payload));
}catch(e) {alert(e)}
}
The above code return data:image/jpg;base64,
as result will be empty.
I am assuming that the issue is with .webp
Here is the site I am trying to scrap images from https://manganato.com/
And for those that want a repredusable code, it is not possible as this code has to be run from inside a webview so no need to ask.
Here is the whole react-native
component
import WebView from "react-native-webview";
import { Html } from "../native";
import * as React from "react";
export default () => {
const state = buildState({
loading: context.parser.find(context.player.novel.parserName)?.protectedChapter == true
}).build();
const webview = useRef();
context.useEffect(() => {
processData();
}, "player.currentChapter")
useEffect(() => {
processData();
}, []);
let parser = context.parser.find(
context.player.book.parserName
);
let processData = () => {
parser = context.parser.find(
context.player.book.parserName
);
if (context.parser.find(context.player.novel.parserName)?.protectedChapter != true)
return;
if (parser?.protectedChapter !== true || state.loading)
return;
if (context.player.currentChapter?.content?.has()) {
return;
}
state.loading = true;
}
let currentUrl = context.player.currentChapter?.url;
const script = `
try {
const getImage = async function (img) {
let src = img.getAttribute("src")
return new Promise(
async (onSuccess, onError) => {
try {
const response = await fetch(src, {
mode: 'no-cors',
referer:"https://chapmanganato.to/",
accept: "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8",
"accept-encoding":"gzip, deflate, br, zstd",
"user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
});
const blob = await response.blob();
const reader = new FileReader();
reader.onerror = function (e) {
console.error(e);
alert(e)
onSuccess("");
}
reader.onload = function () {
if (reader.result)
onSuccess("data:image/jpg;base64,"+reader.result);
else onSuccess("");
};
reader.readAsDataURL(blob);
} catch (e) {
console.error(e);
alert(e)
onSuccess("");
}
}
);
}
const getImages = async function () {
try{
let imgArray = [];
let imgs = [...document.querySelectorAll("${parser?.selector}")];
for (let img of imgs) {
let src = await getImage(img);
if (src && src.length>10)
imgArray.push(src)
}
var payload = {
name: "images",
url: "${currentUrl}",
data: imgArray
};
window.ReactNativeWebView.postMessage(JSON.stringify(payload));
}catch(e) {alert(e)}
}
const getHtml = async function () {
var payload = {
name: "html",
url: "${currentUrl}",
data: document.querySelector("${parser?.selector}").outerHTML
};
window.ReactNativeWebView.postMessage(JSON.stringify(payload));
}
const parse = function () {
if ("${parser.type}" == "Manga")
getImages();
else getHtml();
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", (event) => {
parse();
});
} else {
parse()
}
} catch (e) {
alert(e)
}true;`;
let web = (state.loading && context.parser.find(context.player.novel.parserName)?.protectedChapter == true ? (
<WebView
ref={(r) => webview.current = r}
injectedJavaScript={script}
nestedScrollEnabled={true}
cacheEnabled={true}
source={{
uri: currentUrl,
baseUrl: ""
}}
onMessage={async ({ nativeEvent }) => {
let data = JSON.parse(nativeEvent.data);
//console.warn(data.url, currentUrl)
if (data.name === "images") {
console.log(data.data[0])
data.data = data.data.map(x => `<img src="${x}" />`).join("n");
}
if (currentUrl === data.url) {
context.player.currentChapter.content = data.data;
//console.warn(context.player.novel.type)
await context.player.getChapterContent("hhvh");
state.loading = false;
}
}}
contentMode="mobile"
scalesPageToFit={true}
originWhitelist={["*"]}
scrollEnabled={true}
userAgent="Mozilla/5.0 (Linux; Android 4.1.1; Galaxy Nexus Build/JRO03C) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19"
setSupportMultipleWindows={false}
style={[
{
flexGrow: 1,
zIndex: 70,
flex: 1
}
]}
allowFileAccess={true}
allowFileAccessFromFileURLs={true}
allowUniversalAccessFromFileURLs={
true
}
javaScriptEnabled={true}
/>
) : null);
return { loading: state.loading, web };
}