Thanks for reading. I'm making a Spoiler Blocker Chrome Extension, and as you can imagine that's been quite a journey... Right now I have everything sorted out, except the last part. Because of CORS Policy, I have to use a middleman (Cloudflare worker) to access the Razor API from the extension (returns data about entities). I found an open source code from managing requests with Cors activated for the Cloudflare worker, but it's been days, and I can't get it to send requests as I want it to. I tried predetermining the url to analyze and other stuff, but it just doesn't work.
´´´
The API: https://www.textrazor.com/docs/rest
fetch('https://secret.workers.dev/?https://api.textrazor.com', {
method: 'POST',
body: JSON.stringify({
'extractors': 'entities,sentences',
'text': txt
}),
headers: {
'x-cors-headers': JSON.stringify({
'Content-Type': 'application/x-www-form-urlencoded',
'X-TextRazor-Key': 'secret',
'Accept-Encoding': 'gzip'
})
}
Cloudflare worker code:
addEventListener("fetch", async event=>{
event.respondWith((async function() {
isOPTIONS = (event.request.method == "OPTIONS");
var origin_url = new URL(event.request.url); ```
function fix(myHeaders) {
// myHeaders.set("Access-Control-Allow-Origin", "*");
myHeaders.set("Access-Control-Allow-Origin", event.request.headers.get("Origin"));
if (isOPTIONS) {
myHeaders.set("Access-Control-Allow-Methods", event.request.headers.get("access-control-request-method"));
acrh = event.request.headers.get("access-control-request-headers");
//myHeaders.set("Access-Control-Allow-Credentials", "true");
if (acrh) {
myHeaders.set("Access-Control-Allow-Headers", acrh);
}
myHeaders.delete("X-Content-Type-Options");
}
return myHeaders;
}
var fetch_url = decodeURIComponent(decodeURIComponent(origin_url.search.substr(1)));
var orig = event.request.headers.get("Origin");
var body = event.request;
var remIp = event.request.headers.get("CF-Connecting-IP");
if ((!isListed(fetch_url, blacklist)) && (isListed(orig, whitelist))) {
xheaders = event.request.headers.get("x-cors-headers");
if (xheaders != null) {
try {
xheaders = JSON.parse(xheaders);
} catch (e) {}
}
if (origin_url.search.startsWith("?")) {
recv_headers = {};
for (var pair of event.request.headers.entries()) {
if ((pair[0].match("^origin") == null) && (pair[0].match("eferer") == null) && (pair[0].match("^cf-") == null) && (pair[0].match("^x-forw") == null) && (pair[0].match("^x-cors-headers") == null)) {
recv_headers[pair[0]] = pair[1];
}
}
if (xheaders != null) {
Object.entries(xheaders).forEach((c)=>recv_headers[c[0]] = c[1]);
}
var myHeaders = new Headers();
myHeaders.append('x-textrazor-key', 'secret');
myHeaders.append('Content-Type', 'application/x-www-form-urlencoded');
var myBody = {
extractors: 'entities,sentences',
url: 'https://en.wikipedia.org/wiki/Marty_McFly'
}
newreq = new Request("https://api.textrazor.com", {
method: 'POST',
headers: myHeaders,
body: myBody
})
var response = await fetch(fetch_url,newreq);
var myHeaders = new Headers(response.headers);
cors_headers = [];
allh = {};
for (var pair of response.headers.entries()) {
cors_headers.push(pair[0]);
allh[pair[0]] = pair[1];
}
cors_headers.push("cors-received-headers");
myHeaders = fix(myHeaders);
myHeaders.set("Access-Control-Expose-Headers", cors_headers.join(","));
myHeaders.set("cors-received-headers", JSON.stringify(allh));
if (isOPTIONS) {
var body = null;
} else {
var body = await response.arrayBuffer();
}
var init = {
headers: myHeaders,
status: (isOPTIONS ? 200 : response.status),
statusText: (isOPTIONS ? "OK" : response.statusText)
};
return new Response(body,init);
} else {
var myHeaders = new Headers();
myHeaders = fix(myHeaders);
if (typeof event.request.cf != "undefined") {
if (typeof event.request.cf.country != "undefined") {
country = event.request.cf.country;
} else
country = false;
if (typeof event.request.cf.colo != "undefined") {
colo = event.request.cf.colo;
} else
colo = false;
} else {
country = false;
colo = false;
}
return new Response(
"CLOUDFLARE-CORS-ANYWHERE\n\n" +
"Source:\nhttps://github.com/Zibri/cloudflare-cors-anywhere\n\n" +
"Usage:\n" + origin_url.origin + "/?uri\n\n" +
"Donate:\nhttps://paypal.me/Zibri/5\n\n" +
"Limits: 100,000 requests/day\n" +
" 1,000 requests/10 minutes\n\n" +
(orig != null ? "Origin: " + orig + "\n" : "") +
"Ip: " + remIp + "\n" +
(country ? "Country: " + country + "\n" : "") +
(colo ? "Datacenter: " + colo + "\n" : "") + "\n" +
((xheaders != null) ? "\nx-cors-headers: " + JSON.stringify(xheaders) : ""),
{status: 200, headers: myHeaders}
);
}
} else {
return new Response(
"Create your own cors proxy</br>\n" +
"<a href='https://github.com/Zibri/cloudflare-cors-anywhere'>https://github.com/Zibri/cloudflare-cors-anywhere</a></br>\n" +
"\nDonate</br>\n" +
"<a href='https://paypal.me/Zibri/5'>https://paypal.me/Zibri/5</a>\n",
{
status: 403,
statusText: 'Forbidden',
headers: {
"Content-Type": "text/html"
}
});
}
}
)());
});
Error: "Please specify a TextRazor request."
Thanks in advance!
EDIT:
So, I tried doing the background thingy. But... it doesn't work background.js after receiving the message from content.js
chrome.runtime.onMessage.addListener(function (msg, sender, value, request, sendResponse) {
if (msg.from == "content") { //get content scripts tab id
contentTabId = sender.tab.id;
var myHeaders = new Headers();
myHeaders.append("x-textrazor-key", "secret");
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
var urlencoded = new URLSearchParams();
urlencoded.append("text", request.txt);
urlencoded.append("extractors", "entities,entailments");
fetch("https://api.textrazor.com/", {
method: 'POST',
headers: myHeaders,
body: urlencoded,
redirect: 'follow'
}).then((response) => sendResponse(response.json()));
return true; // Will respond asynchronously.
}
content.js after receiving the first message from background (that orders it to look up the text from the page the user is on)
chrome.runtime.sendMessage({
contentScriptQuery: "querySpoiler", txt: txt, messsage: { from: "content" }, responseCallback: function (response) {
request = response.json();
When looking onto it in DevTools, runtime.sendMessage arguments and caller return an error: TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them at Function.r (:1:83) at chrome-extension://gbbiidobmakfdibhklcfnadmobpekifb/content.js:61:15
Thanks again!