I am working on a Chrome app and I need to find one of the request urls (the request is initiated in a JS script).
The page script after loading asks for .../online_mektep/lesson/L_(page id)/index.json and I need this page id. How can I find out the URL?
The only way I can see now is to modify the original script with a web request and just get the data before the request. Are there other ways?
Not sure if I completely understand what you're trying to accomplish, however: maybe you can add a listener and get the url. Then you can split the URL afterwards and get the route parameter you want
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
console.log('onBeforeRequest', details.url);
const yourUrl = details.url // example: ".../online_mektep/lesson/L_(page id)/index.json"
const pathArray = yourUrl.split('/')
console.log(pathArray[3].split('_')[1]) // should output (page id)
},
);
I'm trying to find a way in javascript to check which URL is loaded, then have a popup notifying the user to update their old bookmarket and have it redirect to the new location in a few seconds.
For example, the url maybe Http:\abc\myappage and I want to check if they are on the http:\abc site which if they are, the notification pops up and redirects them.
Currently I have a simple redirect to take them to the new site, but I never considered anyone that has an old bookmark which would never get updated if you don't inform them about the change.
Thanks.
You can access the current url from within JavaScript with window.location.
Using window.location you can access the current domain and path, then by setting window.location.href = 'your new site' after a few seconds or after some user interaction will cause the browser to navigate to the supplied url.
if(window.location.host === 'abc'){
alert('This url is no longer valid.');
window.location.href = 'http://abc/myappage
}
You can use window.location to get some information regarding the current url:
window.location.origin in the console on this current page, prints:
"http://stackoverflow.com"
Then you could run some JS logic to check against your other url and use alert() to crete the pop up.
working JSBIN: https://jsbin.com/gijola/edit?js,console
adding code:
function checker (url) {
var here = window.location.origin;
l(here);
if (here !== 'whatever you want to check') {
alert('please update your bookmark!!');
}
}
I am trying to match a token (string token) in the RSS feed using casperjs waitFor() but it does not seem to work. There are other ways (not using polling) to get around but I need to poll for it. Here is the code snippet:
casper.then(function() {
this.waitFor(function matchToken() {
return this.evaluate(function() {
if(!this.resourceExists(token)) {
this.reload();
return false;
}
return true;
});
});
});
The updates to rss url are not dynamic and hence, a refresh would be needed to check for the token. But it seems (from the access log) that I am not getting any hits (reload not working) on the rss url. Ideally, I would want to refresh the page if it doesn't see the token and then check for the token again & it should keep doing that until the waitFor times out.
I also tried using assertTextExists() instead of resourceExists() but even that did not work.
I am using PhantomJS (1.9.7) & the url is: https://secure.hyper-reach.com:488/rss/323708
The token I am looking for is --> item/272935. If you look at the url I have mentioned above, you will find this in a each guid tag. The reason why I am including "item/" also as a part of my token is so that it doesn't match any other numbers incorrectly.
evaluate() is the sandboxed page context. Anything inside of it doesn't have access to variables defined outside and this refers to window of the page and not casper. You don't need the evaluate() function here, since you don't access the page context.
The other thing is that casper.resourceExists() works on the resource meta data such as URL and request headers. It seems that you want to check the content of the resource. If you used casper.thenOpen() or casper.open() to open the RSS feed, then you can check with casper.getPageContent(), if the text exists.
The actual problem with your code is that you mix synchronous and asynchronous code in a way that won't work. waitFor() is the wrong tool for the job, because you need to reload in the middle of its execution, but the check function is called so fast that there probably won't be a complete page load to actually test it.
You need to recursively check whether the document is changed to your liking.
var tokenTrials = 0,
tokenFound = false;
function matchToken(){
if (this.getPageContent().indexOf(token) === -1) {
// token was not found
tokenTrials++;
if (tokenTrials < 50) {
this.reload().wait(1000).then(matchToken);
}
} else {
tokenFound = true;
}
}
casper.then(matchToken).then(function(){
test.assertTrue(tokenFound, "Token was found after " + tokenTrials + " trials");
});
You now have to pay to use the google translate api. I'm happy to pay for the service but I can't find a way to use the tts. This is what I'm doing
var GoogleTranslate = function(){
var key = "myapikey"
this.speak = function(words) {
var url = "http://translate.google.com/translate_tts?tl=es&q=" + escape(words) + "&key=" + key
new Audio(url).play();
}
}
but when I do new GoogleTranslate().speak("hola")
The requests to http://translate.google.com/translate_tts never return a response. How do I get this working?
I haven't tried your code yet, so I'm not sure if you should be waiting for the sound to load before you can play it (most likely), but I've written an article about this service recently. The part that matters here is the following:
...if your browser forwards a Referer header with any value other than an empty string (meaning it tells the service which page you clicked the link on) then [Google] will return a 404 (Not Found) http error...
Read the entire article here: Embedding text-to-speech into HTML5 games
So in fact, the service is still there, you just need to hide your referer header. One way to do that is through creating a small gateway script. There's the source for one right in the article.
I have to call domain A.com (which sets the cookies with http) from domain B.com.
All I do on domain B.com is (javascript):
var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.src = "A.com/setCookie?cache=1231213123";
head.appendChild(script);
This sets the cookie on A.com on every browser I've tested, except Safari.
Amazingly this works in IE6, even without the P3P headers.
Is there any way to make this work in Safari?
From the Safari Developer FAQ:
Safari ships with a conservative cookie policy which limits cookie writes to only the pages chosen ("navigated to") by the user. This default conservative policy may confuse frame based sites that attempt to write cookies and fail.
I have found no way to get around this.
If it's worth anything, Chrome doesn't set the cookies either if you use the <script> appending method, but if you have a hidden <img> with the same source, Chrome works in addition to the rest of the browsers (except, again, Safari)
Here is a solution which works:
http://anantgarg.com/2010/02/18/cross-domain-cookies-in-safari/
This might not work for everyone, but I came across this issue because I was serving a React App from a different host than the API, and the solution that ultimately worked was to use DNS:
Our client was being served from www.company-name.com and our API was on company-name.herokuapp.com. By making a CNAME record api.company-name.com --> company-name.herokuapp.com, and having our client use that subdomain for API calls, Safari stopped considering it a "third-party" cookie.
The upside is that there's very little code involved, and it's all using well-established stuff... The downside is that you need some control/ownership over the API host if you're going to use https - they need a certificate that's valid for the client domain, or users will get a certificate warning - so this wouldn't work (at least not for something end-user-facing) if the API in question isn't yours or a partner's.
Working method 2014-2016:
You have to do window.open to the domain / assign a cookie / close the popup, the domain is now safelisted.
Original post # PHP multiple cookies not working on iPad / iPhone browser
There is a bit of an evil trick assuming they have flash installed.
I'm not sure if it still works or not, but Flash'es "Local Shared Objects" aka Flash Cookies could help you circumnavigate Safari's same-domain policies.
Local Shared Object Tutorial
However, it may be complicated to implement, to say the least.
Wiki Article on LSO's
Additonally, LSO's are comming into the light as being a security nightmare:
Electronic Privacy Information Centre on LSO's
Flash Cookies: The Silent Privacy Killer
So think carefully before using them.
A post to a hidden <iframe> can allow you to by-pass this restriction in Safari -- http://gist.github.com/586182:
<?php
header('P3P: CP=HONK');
setcookie('test_cookie', '1', 0, '/');
?>
<div id="test_cookie" style="position: absolute; top: -10000px"></div>
<script>
window.setTimeout(function() {
if (document.cookie.indexOf('test_cookie=1') < 0) {
var
name = 'test_cookie',
div = document.getElementById(name),
iframe = document.createElement('iframe'),
form = document.createElement('form');
iframe.name = name;
iframe.src = 'javascript:false';
div.appendChild(iframe);
form.action = location.toString();
form.method = 'POST';
form.target = name;
div.appendChild(form);
form.submit();
}
}, 10);
</script>
There is a proper workaround for this working in 2015. Let's say there is website y.com which includes iframe with site x.com. The x.com iframe wants to store a cookie. That is not permitted by Safari policy, however, y.com is able to store it. So y.com must listen to messages from x.com and then store the cookie itself.
var _cookieEvMth = window.addEventListener ? "addEventListener" : "attachEvent";
var _cookieEvAction = window[_cookieEvMth];
var _cookieEv = _cookieEvMth == "attachEvent" ? "onmessage" : "message";
_cookieEvAction(_cookieEv, function(evt){
if(evt.data.indexOf('cookieset')!=-1){
var datack = evt.data.split('|');
YOUR_CUSTOM_COOKIE_SAVE_METHOD(datack[1],datack[2],datack[3]);
}
},false);
When x.com needs to store the cookie, it must post a message to y.com:
window.parent.postMessage('cookieset|'+ckName+'|'+ckVal+'|'+days,'*');
Also you can work your way to post message to the iframe if you want to read the cookie. Or you can include it as parameter in x.com iframe url using javascript:
iframe.setAttribute('url','x.com/?cookieval='+YOUR_COOKIE_GET_METHOD('cookiename'));
A workaround we just came up with at my job was to set the cookie via a window.open() - it may not be optimal for you (as you'll have an ugly ass popup window open), but it worked well for us. We had to have a popup window open anyway for OAuth authentication.
So the jist of what we did was:
User clicks a link from B.com
Popup window opens to A.com/setCookie
A.com sets its cookie, and then redirects to B.com in the proper place
Again, not valid in all solutions, but it worked in ours. Hope this helps.
I know this question is rather old, but this helped me to solve cookies problem:
var cookieForm = document.createElement("form");
cookieForm.action = "A.com/setCookie?cache=1231213123";
cookieForm.method = "post";
document.body.appendChild(cookieForm);
cookieForm.submit();
The idea to make a form post on a page that sets your cookies.
*EDIT*
This workaround has been reported closed in WebKit.
Luca,
Ok, so this answer is two years old, but... you can set a cookie from an iframe if you post a form to a hidden iframe. You can do this by creating a form:
<form id="myiframe" action="http://yourdomain.com" method="POST" target="iframe_target">
Then in Javascript, get a reference to the form and call submit:
document.getElementsByTagName('form')[0].submit();
You can listen to the iframe's onload, or you can have your iframe action page issue some javascript that signals the load. I have tested this in Safari and Chrome, and it works.
Cheers.
Perhaps pragmatically create and click a link with an href="A.com/setCookie?cache=1231213123" and a target attribute pointing to a hidden iframe. That may bypass Safari's policy of user navigation for setting cookies (I don't have Safari handy to test.)
I did some extensive investigation around this when I was trying to deploy a site that used Windows Live ID, which depended on the ability to be able to set 3rd party cookies in order to log out. It just... didn't work. Nothing we could do would get it to work. The Live ID team also did extensive investigation and their answer was "can't make it work".
Note this line:
script.src = "A.com/setCookie?cache=1231213123";
I could not get this working until I added the http, i.e.
script.src = "http://A.com/setCookie?cache=1231213123";
I found a simple solution. You just need for first time setting cookie to check if request come from the same origin or not, if not as usual you need to return into iframe a script that will repeat this request, already having permission to assign cookie. After that you can do other request directly through iframe accessing this cookie. This helped me in my tracking system. Try, this works well.
Its worth noting that this restriction in Safari doesn't apply across subdomains. So if you directly visit sitea.com, then you can set cookies from subdomain.sitea.com without direct user interaction (iframe/JavaScript).
This was relevant for my case when developing an API. If you're visitors are arriving at mysite.com, and then you want some JavaScript to interact with your API, then if the API is hosted at api.mysite.com, then it will work on Safari.
Place this JavaScript on the page making cross-domain requests, http://example1.com/index.html:
<script>
var gup = function(name, url) {
if(!url) url = location.href;
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^&#]*)";
var regex = new RegExp( regexS );
var results = regex.exec( url );
return results == null ? null : results[1];
}
var isSafari = navigator.vendor && navigator.vendor.indexOf('Apple') > -1 && navigator.userAgent && !navigator.userAgent.match('CriOS');
var n = gup("activated");
if(isSafari && n == null) {
//browser is Safari and cookies have not yet been activated
var current_url = location.protocol + '//' + location.host + location.pathname;
var query_string = '?callback=' + encodeURIComponent(current_url + '?activated=1');
var new_url = 'http://example2.com/activate.php' + query_string;
window.location.href = new_url;
}
//the rest of your code goes here, and you can now set cross-domain cookies on Safari
</script>
Then create a file on the other server, which needs to set cookies, http://example2.com/activate.php:
<?php
if(isset($_GET['callback'])) {
header('Location: '.$_GET['callback']);
exit();
} else {
//in case callback param is not set, simply go back to previous page
echo "<script>";
echo "window.history.back();";
echo "</script>";
exit();
}
?>
Here's how this works:
When http://example1.com/index.html is first visited, a check is made to see whether the browser is Safari and whether a GET parameter of the name "activated" does not exist. If both conditions are met (which will happen on the first visit for a Safari browser), then the browser is redirected to http://example2.com/activate.php with a GET parameter, "callback", containing the calling URL appended with an "activated" parameter.
http://example2.com/activate.php simply redirects back to the URL contained in the GET parameter, "callback".
When http://example1.index.html is now hit this second time after being redirected-to, the GET parameter, "activated" will now be set, so the conditional from step 1 will not execute, thus allowing the script to continue execution.
This fulfills Safari's requirement of having the browser visit the 3rd party domain at least once in order to start setting cookies.
Try something like:
var w = window.open("A.com/setCookie?cache=1231213123");
w.close();
It may bypass safari's security policy.
It isn't the missing type-attribute thats annoying you ?-)
<script type="text/javascript">
var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.setAttribute("type","text/javascript");
script.src = "A.com/setCookie?cache=1231213123";
head.appendChild(script);
</script>