Are there some tricks to access and iframe, that is on a different domain compared to the main page, in Chrome? A JavaScript solution seems to blocked to prevent cross site issues. The iframe doesn’t work alone, it has to be embedded in the main page to work as expected.
What do you mean by access, and what’s the URL you’re trying to use?
Access = manipulate it using JavaScript. Read/write (mostly read) its content. JavaScript is blocked but maybe you could change the browser’s focus using AppleScript and then use JavaScript or so.
And what URL are you trying to access? Unless I have something to play around with, I can’t help.
Here is a random example
At least when I view this page there is an iframe with a captcha a bit down. You can open the captcha’s iframe in a separate window but it won’t work. I would like to change such a captcha from a visual puzzle to the audio version and then download the audio file. All this is easy to do manually.
Perhaps this helps:
If I understand the idea correctly, you’d get the src
attribute of the iframe
and load the HTML document from there, using XMLHttpRequest. Than you’d create your own HTML document in a new window (preferably), add an iframe
to it and put the loaded HTML document into this iframe
. That might not be enough to fool Google, though.
Thank you. Seems to be worth a try!
There are a lot of double quotes (") in that code - how do you handle that? I tried to define a property myScript
but it chokes on all the double quotes.
I’d not bother using that with AppleScript. Take JavaScript and include the script itself in back quotes. That’s a lot easier.
Backticks? What do you mean?
`
This is a backtick. Kind of a super-quote in JavaScript. Also called template string, I think.
I know what a backtick is (accent grave), but I don’t follow your suggestion include the script itself in back quotes?
My use case in this specific context is that I want to download the audio clip and playback it using some external audio player but then I have the problem with accessing an iframe.
My idea is to write an AS, which includes the script you suggested to access iframes (but then I had the problem of including it as a string, since it contains several layers of quotes and double quotes).
Given this use case, can you elaborate what you mean by not bother using AS? And what you mean by including the script using backticks?
Context: I said that I wouldn’t use AS but instead JavaScript, where I’d simply put the script in backticks to avoid unnecessary quoting troubles.
Exactly the same as I said before: Use JavaScript to avoid all the trouble of single & double quote quoting. Something like
const code = `insert all the code with the quotes etc here, don't worry about line breaks`;
const app = Application("Safari"); // or Chrome
app.doJavaScript(code, {in: app.windows[0]});
To avoid language wars: This is my personal preference. You can, of course, obtain the same results with AS. But I don’t bother with that.
You can read more about JavaScript for Automation here
<iframe>
elements were once the de facto method of displaying content enclosed within a scrollable viewport, back when the browser wars were being fought† between Internet Explorer, Netscape Navigator, and AOLOnline.
Now, of course, they are frequently (only?) used to embed content securely, often when the content originates from a different domain, which, therefore, needs to be loaded using authenticated requests in line with a browser’s CORS policy.
@chrillek suggested using an XMLHttpRequest()
, which I second, although you can also use fetch()
, which operates asynchronously. But communicating with a server back-and-forth feels easier with XMLHttpRequest()
, as it’s event-driven rather than Promised. It has methods for making authenticated server requests, which it sounds like you will need to do (you’ll have to copy-cat the way the website issues its requests, which is probably why your initial attempts were blocked).
If this is a personal endeavour with a view to casually swapping some tedium for a bit of automation, this might be not be a huge saving on tedium depending how much use you get out of it in the long run. You asked about “tricks” in your initial post, of which I am not aware of any (it would probably not be a very secure security policy if there were easy workarounds). However, rather than a trick or a workaround, you do have the option of disabling the CORS policy altogether, which should allow you to load remote resources willy nilly. This is sometimes useful for web developers during debugging, but it’s not something I recommend doing for casual surfing of websites, as the need for sites to authenticate when bringjng in content from elsewhere is what prevents a hacker simply injecting code into a webpage and showing you false content, or sending your private data to a different server. But if you’re fine with that, then you can launch a separate Chrome instance from the commandline and run it with (I think) the --disable-web-security
option flag.
†SPOILER: They all lost.
So you mean using JS also when I script e.g., VLC to playback that downloaded audio?
If that is the case, it makes some sense. The problem is just that my preferred (= that I know reasonably well) languages are Python and Java. AS comes after that and I suck at JS
Therefore, just because I don’t want to spend the time to improve my JS, how would you suggest I include the linked solution in an AS, with all its nested quotes and double quotes?
Why not?
If you know Python and Java, JS shouldn’t be a problem for you. Method names are shorter than in Java, and you don’t need to follow indentation rules.
I don’t do AS. You could probably put the JS code in a file though and run that with run script
.
To make a string quotable for inclusion within an AppleScript, insert a single \
character immediately to the left of every occurrence of "
and \
, then enclose the entire string within a pair of "
characters.
I have managed to load the script now but I don’t understand how to use it. Do you think you could give a short (pseudo)code example?
Which script exactly, and where did you „load“ it and how?
I put it into an external file and loaded it into a string, thus avoiding the issue with quotations.
That is not a script but a module definition. You must call methods defined in this module to do something. But that’s beyond me – I simply posted the link to this code originally because it seemed to get close to what you want to do.
You could try asking the author of the original code how it is supposed to be used.