Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: added a new parameter -js to javascript injection in headless #2066

Open
wants to merge 11 commits into
base: dev
Choose a base branch
from

Conversation

michael2to3
Copy link
Contributor

@michael2to3 michael2to3 commented Jan 11, 2025

Now the -js and --javascript-inject options execute code in the session browser without a head to change, for example, "local storage` or any other scripts
Example:
index.html

<!DOCTYPE html>
<html>

<head>
	<title>check</title>
</head>

<body>
	<h1>check</h1>
	<script>
		const check = () => {
			const h1 = document.querySelector('h1')
			h1.innerText += JSON.stringify(window.localStorage);
			h1.innerHTML += '<br />';
		}
		check();
		setInterval(() => {
			check();
		}, 1000);

	</script>
</body>

</html>

t.js tt.js ttt.js

() => window.localStorage.setItem("a", "boba") // t.js
() => window.localStorage.setItem("ab", "oba") // tt.js
() => window.localStorage.setItem("abo", "ba") // ttt.js
echo 'http://127.0.0.1:8888/' | ./httpx -sid 15 -js "$(cat ./t.js)" -ss -srd ./test -js "$(cat ./tt.js)" --javascript-inject $(cat tt.js)

aeac78fedf7723ec14905191d3d34d975109f9b9

If something needs improvement, then write, I am open to change

@michael2to3 michael2to3 changed the title Feat: add new param -js to injection javascript in headless Feat: added a new parameter -js to javascript injection in headless Jan 11, 2025
@ehsandeep ehsandeep changed the base branch from main to dev January 11, 2025 07:33
@ehsandeep
Copy link
Member

@michael2to3 thank you for the PR, can you please create issue and link back to this PR with information including use case and example.

@michael2to3
Copy link
Contributor Author

Well done: #2067

Copy link
Member

@dwisiswant0 dwisiswant0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should execute if the flag isn't an empty string, regardless of whether the user uses the -ss/-screenshot flag. There should also be a dedicated method for this, separate from the ScreenshotWithBody method (something like EvalJavaScript, etc.). It should run after the DOM Content Loaded page lifecycle event.

@@ -390,6 +392,7 @@ func ParseOptions() *Options {
flagSet.BoolVarP(&options.NoHeadlessBody, "exclude-headless-body", "ehb", false, "enable excluding headless header from json output"),
flagSet.DurationVarP(&options.ScreenshotTimeout, "screenshot-timeout", "st", 10*time.Second, "set timeout for screenshot in seconds"),
flagSet.DurationVarP(&options.ScreenshotIdle, "screenshot-idle", "sid", 1*time.Second, "set idle time before taking screenshot in seconds"),
flagSet.StringSliceVarP(&options.JavascriptInject, "javascript-inject", "js", nil, "set javascript to inject", goflags.StringSliceOptions),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
flagSet.StringSliceVarP(&options.JavascriptInject, "javascript-inject", "js", nil, "set javascript to inject", goflags.StringSliceOptions),
flagSet.StringSliceVarP(&options.JavascriptInject, "javascript-code", "jsc", nil, "execute JavaScript code after DOM content loaded", goflags.StringSliceOptions),

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@michael2to3
Copy link
Contributor Author

If the JavaScript is executed only after waitStable or domStable, the user won't have the ability to control the state before the DOM is fully loaded, which is sometimes necessary. If the user needs to execute code specifically after the DOM is loaded, they can choose the event that suits their needs best. For instance, in the case of DOM stability, window.onload = () => {...} seems appropriate.

Thus, I suggest executing eval immediately after navigation. This approach will provide more flexibility for the user

@dwisiswant0
Copy link
Member

If the JavaScript is executed only after waitStable or domStable, the user won't have the ability to control the state before the DOM is fully loaded, which is sometimes necessary. [...]

Can you give an example use case for that?

Thus, I suggest executing eval immediately after navigation. This approach will provide more flexibility for the user

Looks like we need to update the flag description, specifically by removing the phrase "after DOM content loaded".

After reviewing the a7e821c changes, EvalJavascript is still being invoked inside ScreenshotWithBody method, which relies on the -ss/-screenshot flag. it really should be independent of that.

@michael2to3
Copy link
Contributor Author

Can you give an example use case for that?

In my case, the website loaded JavaScript immediately and redirected to the registration page if it didn’t find specific variables in localStorage. Executing JavaScript right away allowed me to set those variables before the check.

Looks like we need to update the flag description, specifically by removing the phrase "after DOM content loaded".

I’ve updated the flag description as suggested – apologies for missing that earlier.

After reviewing the a7e821c changes, EvalJavascript is still being invoked inside ScreenshotWithBody method, which relies on the -ss/-screenshot flag. it really should be independent of that.

The dependency of -jsc on -ss is intentional since httpx only executes JavaScript in headless mode, enabled by the -ss option. Without it, JavaScript execution won’t occur.

If I’m mistaken and httpx can run JavaScript without -ss, please let me know, and I’ll adjust the code.

@dwisiswant0
Copy link
Member

In my case, the website loaded JavaScript immediately and redirected to the registration page if it didn’t find specific variables in localStorage. Executing JavaScript right away allowed me to set those variables before the check.

+1 makes sense.

If I’m mistaken and httpx can run JavaScript without -ss, please let me know, and I’ll adjust the code.

Thoughts on this, @Mzack9999?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants