Unfortunately I have to use VPN to visit google, including recapcha. Some chrome extensions can redirect those to recaptcha.net, otherwise I won't see captcha at all.....works in most cases, but sometimes not. Now I got this site, the source code shows replacement did not happen.
It's like:
<div class="gglcptch gglcptch_v3"><input type="hidden" id="g-recaptcha-response" name="g-recaptcha-response"> <script src="https://www.google.com/recaptcha/api.js?render=6LesAYIUAAAAAMj2s2eUJfWEJNiAZTdeGONG5r5w"></script>
<script>
grecaptcha.ready(function() {
grecaptcha.execute('6LesAYIUAAAAAMj2s2eUJfWEJNiAZTdeGONG5r5w', {action: 'BWS_reCaptcha'}).then(function(token) {
document.querySelectorAll( "#g-recaptcha-response" ).forEach( elem => ( elem.value = token ) );
});
});
</script></div>
So I essembled this code:
$(document).ready(function(){
$('.gglcptch gglcptch_v3').html(function(index,html){
return html.replace(/www\.google\.com\/recaptcha\//g,'recaptcha.net/recaptcha/');
});
});
Chrome dev did not show error, but still replacement not happening.
So my guess is the sequence? when document.ready, script already done running?
What should I do?
1. Your selector is wrong. Should be like the below one:
$('.gglcptch.gglcptch_v3').html(
// ... your function
)
$(document).ready(function(){
$('.gglcptch.gglcptch_v3').html(function(index,html){
return html.replace(/www\.google\.com\/recaptcha\//g,'recaptcha.net/recaptcha/');
});
console.log($('.gglcptch.gglcptch_v3 script').attr('src'))
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="gglcptch gglcptch_v3"><input type="hidden" id="g-recaptcha-response" name="g-recaptcha-response"> <script src="https://www.google.com/recaptcha/api.js?render=6LesAYIUAAAAAMj2s2eUJfWEJNiAZTdeGONG5r5w"></script>
<script>
grecaptcha.ready(function() {
grecaptcha.execute('6LesAYIUAAAAAMj2s2eUJfWEJNiAZTdeGONG5r5w', {action: 'BWS_reCaptcha'}).then(function(token) {
document.querySelectorAll( "#g-recaptcha-response" ).forEach( elem => ( elem.value = token ) );
});
});
</script></div>
2. But this won't replace google recaptcha to any other external source.
when document.ready, script already done running?
The answer is: Yes.
3. You should load external script(from recaptcha.net or so).
See e.g. this link: JavaScript - function to load external JS files is needed
Related
Good evening!
I had a working functionality on a sharepoint document library. It's purpose was to copy the name of a file to the title column.
It was working for a long time but after an update to the sharepoint platform it stopped working and i can't figure out why.
The code:
<input type="button" onclick="updateTitleFromName()" value="Update Title from Name" />
<script type="text/javascript" src="/Scripts/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="/Scripts/spjs-utility/spjs-utility.js"></script>
<script type="text/javascript">
function updateTitleFromName(){
var q, res, uRes, count;
count = 0;
q = "<Where><IsNull><FieldRef Name='Title' /></IsNull></Where>";
res = spjs_QueryItems({"listName":_spPageContextInfo.pageListId,"query":q,"viewFields":["ID","FileLeafRef"]});
if(res.count === 0){
alert("No files without title found.");
return;
}
if(!confirm("There are "+res.count+" files to update. The page will appear as frozen while the script is working.\n\nContinue?")){
return;
}
$.each(res.items,function(i,item){
uRes = spjs_updateItem({"listName":_spPageContextInfo.pageListId,"id":item.ID,"data":{"Title":item.FileLeafRef.split(";#")[1]}});
if(!uRes.success){
alert("Could not update the file: "+item.FileLeafRef+" due to the follwing error:\n\n"+uRes.errorText);
}else{
count += 1;
}
});
alert("Updated "+count+" files.");
location.href = location.href;
}
</script>
The error is: TypeError: $spjs is null. And it occurs inside the library spjs-utility library on the spjs_QueryItems call.
Maybe this could be due to a conflictuous library that as added during the updated, but how can i debug this?
Also, if this doesn't work, wouldn't it be simpler to do the same with jQuery? Thats what i'm trying right now, but i'm a beginner as you must have perceived.
Thanks in advance.
Best
I would test if JQuery is loaded or not in your updateTitleFromName function:
if (window.jQuery) {
alert('loaded');
} else {
alert('not loaded');
}
if it is not loaded, try to reference your scripts with absolute urls to see if you can load them:
<script type="text/javascript" src="http://myportal/Scripts/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="http://myportal/Scripts/spjs-utility/spjs-utility.js"></script>
I'm using QUnit for unit testing js and jquery.
My HTML looks like this:
<!DOCTYPE html>
<html>
<head>
<title>QUnit Test Suite</title>
<script src="../lib/jquery.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.16.0.css" type="text/css" media="screen">
<script type="text/javascript" src="http://code.jquery.com/qunit/qunit-1.16.0.js"></script>
<!--This is where I may have to add startPage.html--->
<script src="../login.js"></script>
<script src="../test/myTests.js"></script>
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
</body>
</html>
Currently, I'm adding login.js as shown and I'm getting references correctly to objects defined in login.js.
However, functions in login.js contains references to some dom elements defined in startPage.html which is located elsewhere.
So, if I say $('#login-btn'), it is throwing an error. Is there any way to fix this?
Can I
(a) refer to startPage.html to my qunit page given above?
(b) refer to or load startPage.html in the file where I'm running tests (myTests.js):
QUnit.test( "a test", function( assert ) {
assert.equal( 1, "1", "String '1' and number 1 have the same value" );//works
assert.equal( login.abc, "abc", "Abc" );//works with attributes
assert.equal(($("#userid").val()),'', 'Userid field is present');//fails
assert.equal( login.ValidUserId(), true, "ValidUserId" );//fails with functions
});
Does QUnit provide any method to load Html/php files so they'll be defined prior to testing. Like 'fixtures' in jasmine?
EDIT: Please also tell what to do in case I have startPage.php
There are a couple of ways you can do this. The simplest is just to use the built-in QUnit "fixtures" element. In your QUnit HTML file, simply add any HTML you want in the div with the id of qunit-fixture. Any HTML you put in there will be reset to what it was on load before each test (automatically).
<html>
...
<body>
<div id='qunit'></div>
<div id='qunit-fixture'>
<!-- everything in here is reset before each test -->
<form>
<input id='userid' type='text'>
<input id='login-btn' type='submit'>
</form>
</div>
</body>
</html>
Note that the HTML in the fixture doesn't really have to match what you have in production, but obviously you can do that. Really, you should just be adding the minimal necessary HTML so that you can minimize any side effects on your tests.
The second option is to actually pull in the HTML from that login page and delay the start of the QUnit tests until the HTML loading is complete:
<html>
<head>
...
<script type="text/javascript" src="http://code.jquery.com/qunit/qunit-1.16.0.js"></script>
<script>
// tell QUnit you're not ready to start right away...
QUnit.config.autostart = false;
$.ajax({
url: '/path/to/startPage.html',
dataType: 'html',
success: function(html) {
// find specific elements you want...
var elem = $(html).find(...);
$('#qunit-fixture').append(elem);
QUnit.start(); // ...tell QUnit you're ready to go
}
});
</script>
...
</head>
...
</html>
Another way to do this without using jquery is as follows
QUnit.config.autostart = false;
window.onload = function() {
var xhr = new XMLHttpRequest();
if (xhr) {
xhr.onloadend = function () {
if(xhr.status == 200) {
var txt = xhr.responseText;
var start = txt.indexOf('<body>')+6;
var end = txt.indexOf('</body>');;
var body_text = txt.substring(start, end);
var qunit_fixture_body = document.getElementById('qunit-fixture');
qunit_fixture_body.innerHTML = body_text;
}
QUnit.start();
}
xhr.open("GET", "index.html");
xhr.send();
} else {
QUnit.start(); //If getting the html file from server fails run tests and fail anyway
}
}
So, I've found this JSFiddle example. In JSFiddle works well, the problem is that, even if I search any != from "advogados" (just testing), the browser goes to: http://www.site.com/index.html?procura=teste
No jQuery conflict, no html issue.
Here's JS
$("#procura").on("submit", function(event){
// prevent form from being truely submitted
event.preventDefault();
// get value of text box
name = $("#procura_texto").val();
// compare lower case, as you don't know what they will enter into the field.
if (name.toLowerCase() == "advogados")
{
//redirect the user..
window.location.href = "http://jornalexemplo.com.br/lista%20online/advogados.html";
}
else
{
alert("no redirect..(entered: " + name + ")");
}
});
If your javascript is somewhere in your HTML before your <form> your $("#procura") will be an empty set, so the submit-action won't be bound to anything. Try following code:
<html>
<head>
<script type="text/javascript" src="/path/to/your/jquery.js"></script>
<script type="text/javascript">
$(function() {
// This code will be run if your document is completely
// parsed by the browser, thus all below elements are
// accessible
$('#procura').on('submit', ....);
});
</script>
</head>
<body>
<form id="procura">...</form>
</body>
</html>
$(function() {}) is also known as $(document).ready(function() {}), (documentation)
You aren't defining the variable name. http://jsfiddle.net/zwbRa/59/
var name = $("#procura_texto").val();
Is there a solution to get the "foo bar" in JS (with jQuery ?) in this code ?
<!DOCTYPE html>
<html>
<body role="application" onload="foo bar">
<div>...</div>
</body>
</html>
I'am using PhantomJS in my script.
EDIT: "foo bar" is an example. It's juste the value I would get.
EDIT 2: my code (wich don't work) is http://paste.awesom.eu/nca&ln.
EDIT 3: PROBLEM(S) AND SOLUTION
After many hours I find many problems and solutions.
First, the website is only accesible in https and I can't include jQuery file from non https url. That's why I have include the jQuery file from the website.
I have debug this with this code :
page.onConsoleMessage = function(msg) {
console.log(msg);
};
Then, I need to change my user agent because the website has a whitelist.
page.settings.userAgent = 'Mozilla/5.0 (X11; Linux x86_64; rv:25.0) Gecko/20100101 Firefox/25.0';
Finaly the code is:
page.open(url, function(status) {
if ( status === "success" ) {
page.includeJs(url_js_file, function() {
page.evaluate(function() {
console.log("> " + $("body").attr("onload"));
});
phantom.exit();
});
}
});
Thank you for comments and anwers.
It looks like you are not returning your variable out of evaluate.
To do that you must
var bodyonload = page.evaluate(function (s) {
return document.body.getAttribute('onload');
}, 'bodyonload');
You were very close to having it.
Here is your code where it returns an object rather than just a variable. I figured it could be useful.
page.open(url, function (status) {
if (status !== 'success') {
console.log('FAILED: ' + status);
} else {
var result = page.evaluate(function (s) {
var result = {
bodyOnLoad: document.body.getAttribute('onload'),
documentTitle: document.title
};
return result;
}, 'result');
console.log(result.bodyOnLoad);
}
phantom.exit();
});
Hope that helps
Edit:
Looked at it some more and perhaps there is a problem with your reference to jquery in page.injectJs(), is jquery in the same directory?
There should be no space between function name, It should like <body role="application" onload="foobar()"> instead of <body role="application" onload="foo bar">
In between HTML head tag,
<script>
function foobar(){
alert('Am loaded');
}
</script>
Try:
document.body.getAttribute("onload")
If you want to get the actual, literal value of onload, use $('body').attr('onload'). This will return the value of any attribute, for any element (assuming jQuery is being used). If not using jQuery, document.body.getAttribute("onload") should do the trick.
Keep in mind that since PhantomJS technically runs outside of the targeted page's DOM, you need to wrap any DOM scripts in page.evaluate:
page.evaluate(function () {
// put your $('body').attr('onload') bit here.
});
This worked for me for returning the value in onload.
<!DOCTYPE html>
<html>
<body role="application" onload="foo bar">
<div>...</div>
<script src="http://code.jquery.com/jquery.js"></script>
<script>
console.log($("body").attr("onload"));
</script>
</body>
</html>
I would like to print the content of a script tag is that possible with jquery?
index.html
<script type="text/javascript">
function sendRequest(uri, handler)
{
}
</script>
Code
alert($("script")[0].???);
result
function sendRequest(uri, handler)
{
}
Just give your script tag an id:
<div></div>
<script id='script' type='text/javascript'>
$('div').html($('#script').html());
</script>
http://jsfiddle.net/UBw44/
You can use native Javascript to do this!
This will print the content of the first script in the document:
alert(document.getElementsByTagName("script")[0].innerHTML);
This will print the content of the script that has the id => "myscript":
alert(document.getElementById("myscript").innerHTML);
Try this:
console.log(($("script")[0]).innerHTML);
You may use document.getElementsByTagName("script") to get an HTMLCollection with all scripts, then iterate it to obtain the text of each script. Obviously you can get text only for local javascript. For external script (src=) you must use an ajax call to get the text.
Using jQuery something like this:
var scripts=document.getElementsByTagName("script");
for(var i=0; i<scripts.length; i++){
script_text=scripts[i].text;
if(script_text.trim()!==""){ // local script text
// so something with script_text ...
}
else{ // external script get with src=...
$.when($.get(scripts[i].src))
.done(function(script_text) {
// so something with script_text ...
});
}
}
The proper way to get access to current script is document.scripts (which is array like HTMLCollection), the last element is always current script because they are processed and added to that list in order of parsing and executing.
var len = document.scripts.length;
console.log(document.scripts[len - 1].innerHTML);
The only caveat is that you can't use any setTimeout or event handler that will delay the code execution (because next script in html can be parsed and added when your code will execute).
EDIT: Right now the proper way is to use document.currentScript. The only reason not to use this solution is IE. If you're force to support this browser use original solution.
Printing internal script:
var isIE = !document.currentScript;
function renderPRE( script, codeScriptName ){
if (isIE) return;
var jsCode = script.innerHTML.trim();
// escape angled brackets between two _ESCAPE_START_ and _ESCAPE_END_ comments
let textsToEscape = jsCode.match(new RegExp("// _ESCAPE_START_([^]*?)// _ESCAPE_END_", 'mg'));
if (textsToEscape) {
textsToEscape.forEach(textToEscape => {
jsCode = jsCode.replace(textToEscape, textToEscape.replace(/</g, "<")
.replace(/>/g, ">")
.replace("// _ESCAPE_START_", "")
.replace("// _ESCAPE_END_", "")
.trim());
});
}
script.insertAdjacentHTML('afterend', "<pre class='language-js'><code>" + jsCode + "</code></pre>");
}
<script>
// print this script:
let localScript = document.currentScript;
setTimeout(function(){
renderPRE(localScript)
}, 1000);
</script>
Printing external script using XHR (AJAX):
var src = "https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js";
// Exmaple from:
// https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest
function reqListener(){
console.log( this.responseText );
}
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", src);
oReq.send();
*DEPRECATED*: Without XHR (AKA Ajax)
If you want to print the contents of an external script (file must reside on the same domain), then it's possible to use a <link> tag with the rel="import" attribute and then place the script's source in the href attribute. Here's a working example for this site:
<!DOCTYPE html>
<html lang="en">
<head>
...
<link rel="import" href="autobiographical-number.js">
...
</head>
<body>
<script>
var importedScriptElm = document.querySelector('link[rel="import"]'),
scriptText = scriptText.import.body.innerHTML;
document.currentScript.insertAdjacentHTML('afterend', "<pre>" + scriptText + "</pre>");
</script>
</body>
</html>
This is still experimental technology, part of web-components. read more on MDN