Closed cyb233 closed 2 years ago
maybe I found why exception: window.__BASE_URL__
is undefined
. how to fix it?
left proxied by cf and another not
The error is pointing to window.__BASE_URL__
being undefined indeed. This variable is set in 2 places:
Second path is activated when the main scripts fail to load from expected path. First path is activated when the main script loads from expected path AND it did not fail before.
Either way, I see no way how this code could not be set by the time we attempt to connect websocket.
To give more insight, I need you to verify neither of those paths activated. To do this, please open www/index.html
and add a console.log
statements in highlighted places:
If none of those happens to fire when CF's proxy is enabled, I'd appriciate if you could show full rendered HTML (right click > View Source > copy whole source). I suspect CloudFlare may be doing some magic behind the scenes which prevents the script from working in predictable manner.
My bets what is going on:
<script src="main.js"/>
being evaluated before inline script due to it's higher placement in HTML. I think this may be the case, as given there shouldn't be async
or defer
modifiers, browser have no reason to skip evaluating available script right away.main.js
script, the result is ultimately the same as above, the main script is parsed before inline script mounts load watcher and onload
is never captured.(options on screenshots may not represent the actual CF features at fault, but you can try turning them off)
I'm going to be unhelpful and say a classic: works for me.
it seems realy caused by Rocket Loader™
, it works well when I turn off it. thx.
I think it can be added into faq.
@cyb233 Could you please provide the rendered HTML for reference? I am positive we could adjust our code to work with Rocket Loader :)
with Rocket Loader or without?
souce file:
index.txt
view-source without Rocket Loader:
index_view-source_without_RL.txt
view-source with Rocket Loader:
(why github said We don’t support that file type.
I jist want upload txt file)
<!doctype html>
<html>
<head>
<title>ASF</title>
<meta charset="utf-8">
<meta name="robots" content="noindex">
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
<meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport">
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600" rel="stylesheet">
<link href="/manifest.json" rel="manifest" crossorigin="use-credentials">
<link href="/images/logo.png" rel="shortcut icon">
<script defer="defer" src="/scripts/main.5ed0908.bundle.js" integrity="sha256-9JCW9sijsEmadSNVqk+HoLPjyfCDMsAvKgzrHhfYvEA= sha384-1Xs/h7NuREr2Qv9B32I34OZo0CPYmk/jzlp8pACL+PNCXeOiLSoUl1+Zr/03/kLE" crossorigin="anonymous" type="8c362c86887f4ed57e9e8237-text/javascript"></script>
<script async src='/cdn-cgi/challenge-platform/h/g/scripts/invisible.js?ts=1651795200'></script></head>
<body>
<div id="app"></div>
<script type="8c362c86887f4ed57e9e8237-text/javascript">
console.log("Change success #1");
const mainScript = document.querySelector('script[src^="/scripts/main"]');
mainScript.onerror = createErrorHandler(window.location.pathname, mainScript.getAttribute('src'), mainScript.getAttribute('integrity'));
mainScript.onload = createLoadHandler(mainScript.onerror);
function addScript(path, integrity) {
const scriptElement = document.createElement('script');
scriptElement.src = path;
scriptElement.async = true;
if (integrity) {
scriptElement.integrity = integrity;
scriptElement.crossOrigin = 'anonymous';
}
document.head.appendChild(scriptElement);
return scriptElement;
}
function stripLastPart(path) {
const lastIndexOfSlash = path.lastIndexOf('/');
return path.slice(0, lastIndexOfSlash);
}
function createLoadHandler(onError) {
return function() {
console.log("Load Handler fired");
// onLoad is fired when script is loaded. We do not want to be fooled by server returning index.html
// Check if the script is indeed working can be achieved by testing __ASF_UI_LOADED__ property set in index.js
if (!window.__ASF_UI_LOADED__) return onError();
// It is possible we loaded main script on first attempt
if (!window.__BASE_PATH__) {
// Other parts of the app use __BASE_PATH__ and __BASE_URL__, set it anyway
window.__BASE_URL__ = window.location.origin + '/';
window.__BASE_PATH__ = '/';
// We do not need to update resources, as the default path is already good
return;
}
document.querySelector('link[rel="shortcut icon"]').setAttribute('href', `${__BASE_PATH__}images/logo.png`);
document.querySelector('link[rel="manifest"]').setAttribute('href', `${__BASE_PATH__}manifest.json`);
};
}
function createErrorHandler(path, scriptPath, integrity) {
return function() {
console.log("Load Handler fired");
// We are likely working with /<prefix>. Possible <browser path>:
// a) We are on /<prefix>
// b) We are on nested page /<prefix>/<page>
// c) We are on deeply nested page /<prefix>/<page A>/<page B>
// Either way, we need to load script from /<prefix>/<script path>
// We start from <browser path> and work recursively by striping
// parts after last "/" character:
// 1. /<prefix>/<page A>/<page B>
// 2. /<prefix>/<page A>
// 3. /<prefix>
const normalizedPath = path.endsWith('/') ? path.slice(0, -1) : path;
if (!normalizedPath.length) return; // Give up
// These properties needs to be set properly prior to script execution
// Otherwise we will be downloading script chunks from base (incorrect) path
window.__BASE_URL__ = window.location.href.replace(window.location.pathname, normalizedPath + '/');
window.__BASE_PATH__ = normalizedPath + '/';
// Add new script tag using new path
const newScriptPath = normalizedPath + scriptPath;
const newScript = addScript(newScriptPath, integrity);
// We found the path! Replace other resources
newScript.onerror = createErrorHandler(stripLastPart(normalizedPath), scriptPath, integrity);
newScript.onload = createLoadHandler(newScript.onerror);
};
}
</script>
<script src="/cdn-cgi/scripts/7d0fa10a/cloudflare-static/rocket-loader.min.js" data-cf-settings="8c362c86887f4ed57e9e8237-|49" defer=""></script><script type="text/javascript">(function(){window['__CF$cv$params']={r:'706d6fb0e8867cf1',m:'3TjaQTEm0_onhLIkmBVGfRXusY3PHsPXzCZ0Y3mMMw8-1651795233-0-AaxiOjn9fIm9ddZSuCX48bEj0SoTGvdTLC4CLt6F7f+co9DV0VHnEhC/p0KfgRyYey0Cdms4+L/slDTx3YssNPQoluL5+JSNGJsTPcSxHRnjn0Z0vV/FutJzJuxKN1E4zw==',s:[0xc13ceb3c74,0x69fea67a9a],u:'/cdn-cgi/challenge-platform/h/g'}})();</script></body>
</html>
Checklist
ASF version
Latest stable release
ASF-ui version
892742c
Bug description
when I use host with cloud flarein
Proxied
mode, and enter the log page, it will throw exception:TypeError: Cannot read properties of undefined (reading 'replace')
, and it will no problem without cloud flare. see also: https://github.com/JustArchiNET/ArchiSteamFarm/discussions/2563it will happen when set cloud flare in
Development Mode
and solved when set the hostDNS only
. it's only happen in log pageExpected behavior
I exprcted that I can see the log, and protect my server by cloud flare.
Actual behavior
when I protect my server by cloud flare, I can't see any log.
Steps to reproduce
when use cloud flare to set a DNS Record in
Proxied
mode:Possible reason/solution
it's only happenned in cloud flare with Proxied, I'm not sure if the problem is cloud flare or the framework.
Can you help us with this bug report?
Somehow, I can test and offer feedback, but can't code
Global ASF.json config file
No response
BotName.json config of all affected bot instances
No response
Additional info
if it can be resolved, I have time to test, and if not, I want know why.