Retrieve a cookie from a different path - javascript

My current document URL is http: //127.0.0.1/foo and I need to change the value of a cookie for http: //127.0.0.1/bar.
document.cookie is empty because document's URL is foo.
For the moment, I just want to read the cookie value.
Any clue?

When you create the cookie, if you set the path to '/' instead of 'foo' you will be able to read it anywhere on the domain, including '/foo', '/bar', etc.

You can create an <iframe> pointed at a resource inside /bar, and cross-frame-script into it. eg:
<iframe src="/bar/blank.html" id="barframe"></iframe>
var barframe= document.getElementById('barframe');
var bardocument= 'contentDocument' in barframe? barframe.contentDocument : barframe.contentWindow.document; // IE compat
alert(bardocument.cookie);
Cookie path= is a convenience measure to prevent accidental cookie name clashes. Given that different paths share a JavaScript origin, it is not an effective security mechanism.

You can't access cookies from a different path - otherwise it would be a security hole.
The only way I can think of is making /bar set a cookie whose path=/ so that all pages in / (including /foo) could access it.

As JJ and grawity have mentioned there is no way you can do this from your page. However, you have a work around.
i. Place an iframe which points to http://localhost/bar. Have a hidden element on the "bar" page where you store the cookie value. (let this iframe be 1*1 size so it is not visible).
ii. Use JavaScript on "foo" page to fetch the cookie value.
A similar approach (with modifications) can be used to write the cookie value too!
Thanks,
Ramjee.

Related

Manually generate GA linker parameter with gtag (GA4)

Background
To pass a client_id from one domain to another, Google supports adding a "linker" parameter to outgoing Links that are part of the cross-domain tracking setup. This linker parameter contains the client_id, session_id (I believe, information about Google Ads, e.g. gclid) and a basic fingerprint + timestamp. On the receiving domain, if the browser fingerprint matches and the timestamp is not too far in the past, the passed client_id and session_id are stored in a first party cookie on the 2nd domain and consequently used.
analytics.js / GA-UA
With analytics.js (GA-UA) you could easily do the following, to decorate URLs manually:
function decorateUrl(urlString) {
var ga = window[window['GoogleAnalyticsObject']];
var tracker;
if (ga && typeof ga.getAll === 'function') {
tracker = ga.getAll()[0]; // Uses the first tracker created on the page
urlString = (new window.gaplugins.Linker(tracker)).decorate(urlString);
}
return urlString;
}
Yet, when only gtag is loaded, window.ga and window.gaplugins are not defined. As far as I see, there is currently no documented way to manually generate links with the linker parameter with gtag.
In Google's documentation, they suggest setting up the linker manually. (https://support.google.com/analytics/answer/10071811?hl=en#zippy=%2Cmanual-setup)
But this has several disadvantages, e.g. I have to create a custom "fingerprint" logic (so that decorated URLs are not shared) and e.g. Google Ads information is not included.
Either way, I would like to use the internal gtag logic to decorate URLs.
"Hacky" Workaround Solution
gtag automatically decorates a tags (as soon as they're clicked) that lead to a cross-domain-tracking domain specified in the GA4 data stream settings (e.g. "test.com"), but I specifically need to decorate URLs manually (i.e. without immediately redirecting to them).
I thought about doing the following:
Create a dummy, hidden a tag with the URL to decorate
Prevent redirection with onclick='event.preventDefault();'
Simulate click on hidden element so that gtag automatically adds the linker url parameter to the href attribute
Extract new href attribute
Remove hidden element
function decorateUrlGtag(urlString) {
var tempAnchorEl = document.createElement("a");
tempAnchorEl.setAttribute("type", "hidden");
tempAnchorEl.setAttribute("href", urlString);
tempAnchorEl.setAttribute("onclick", "event.preventDefault(); return false");
document.body.appendChild(tempAnchorEl);
tempAnchorEl.click();
var urlWithLinker = tempAnchorEl.href;
tempAnchorEl.remove();
return urlWithLinker;
}
This also does not work, because gtag does not seem to register the tempAnchorEl.click(); call. If I click the link manually, the URL is decorated - as expected.
Suggested Solutions
The solutions outlined here (Google Analytics gtag.js Manually adding the linker cross-domain parameter to URLs) also do not work for me:
Answer: Even after gtag is initiated, I do not see a global ga element
Answer: Same problem (no ga defined)
Do you (1) know if there is a way to generate the linker parameter manually with gtag that I have overlooked, (2) know how to make my "hacky" solution work or (3) have another possible solution?
I haven't grokked this solution, and I am not sure it answers your question directly, but Simo does give an outline of how to configure GA4 cross domain tracking here:
https://www.simoahava.com/gtm-tips/cross-domain-tracking-google-analytics-4/#how-to-configure-cross-domain-tracking-manually
He breaks the problem down into steps but does not go into great detail. He provides one code snippet:
"...you could also load the URL parameter values directly into the GA4 configuration with something like:
gtag('config', 'G-12345', {
// Namespace roll-up trackers
cookie_prefix: 'roll-up',
// Pull in the Client ID from the URL
client_id: (new URLSearchParams(document.location.search)).get('client_id'),
// Pull in the Session ID from the URL
session_id: (new URLSearchParams(document.location.search)).get('session_id')
});
"
Hope that helps!

JS Cookie path not setting

I am using the following Javascript API for setting a cookie:
https://github.com/js-cookie/js-cookie
I am trying to set the path to the current page, but it is setting to the root. My code to set the cookie is:
Cookies.set('timeElapsed', data.seconds, {path: ''});
Which is part of a wider function which is tracking the progress of a Vimeo video, so I can use the cookie to resume from the last play point when the page is returned to.
But the cookie that is being set has the path /, meaning I can't use the same code for other videos on the site.
How can I set the cookie for just the current page?
just remove the path attribute
document.cookie="timeElapsed="+data.seconds;
UPDATE
JSFIDDLE
The code is correct. By default js-cookie creates the cookie valid to all pages inside / path. If you want to make it available to the path of the current page (not the current page), then you use the code:
Cookies.set('timeElapsed', data.seconds, {path: ''});
Basically, in js-cookie, path: '' is the same as document.cookie='name=value'. If no attribute is declared, then it assumes document.cookie='name=value; Path: /' by default.

Deleting the local storage of a specific domain

I'm making an extension and while I can delete all the cookies of a specified domain, I can't delete its local storage.
So for example, if I visited The Telegraph's website, it keeps a local storage in my machine:
Origin: http://www.telegraph.co.uk/
Size on disk: 6.0 KB
I have tried using the remove() method from the storage api:
StorageArea.remove("http://www.telegraph.co.uk/");
and I'm getting the following error:
Error in event handler for browserAction.onClicked: StorageArea is not defined
Stack trace: ReferenceError: StorageArea is not defined
How can I programmatically make this work?
chrome.storage is a completely different API compared to localStorage. The former is only available to extensions, while the latter is specific to the domain of the website.
If you want to modify or clear the data in localStorage for a specific domain, then just insert a content script in the page that invokes localStorage.clear().
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(tab.id, {code: 'localStorage.clear()'});
});
If you want to clear the localStorage of a different origin, you have to load a page from that origin in a tab or frame and insert a content script in it. For example:
// background.js
var f = document.createElement('iframe');
f.sandbox = ''; // Sandboxed = disable scripts, etc.
f.src = 'http://example.com/#someuniqueid';
f.onloadend = function() {
f.remove();
};
// content script, declared in manifest file (read the documentation)
if (location.hash === '#someuniqueid') {
localStorage.clear();
}
try using
StorageArea.clear(function callback)
.remove accepts key string or array of keys to remove specific items.
Also i'm not sure if it will access storage of specific domains.
Try to check url before clearing

Permission denied to call method ChromeWindow.postMessage for iframe inside XUL page

I've an extension, and an XUL file inside it (let's call it A). XUL file contains an <iframe>, where is loaded some web page (let's call it B). B is loaded from the different domain.
A is parent to B. I want to send a message from within B to A using window.parent.postMessage().
I'm getting the following exception:
... permission denied to B to call method ChromeWindow.postMessage
How to fix that error? If there is no way to do that, how can I pass message from B to A?
I am using Firefox 16.0.1 under Windows 7.
I had a very similar problem,
it's just I had a html-popup (local) that couldn't send 'postMessage' to my xul-background-task.
I think I got it to work,
strangely enough by initiating a MessageEvent of my own (the very same thing postMessage does)
but with a (I believe obsolete) fallback.. in short: I brewed something together from MDN and other sites ;)
My script in the content:
var Communicator =
{
postMessage: function(data)
{
// We need some element to attach the event to, since "window" wont work
// let's just use a fallback JSON-stringified textnode
var request = document.createTextNode(JSON.stringify(data));
// and as always attach it to the current contentwindow
document.head.appendChild(request);
// Now let's make a MessageEvent of our own, just like window.postMessage would do
var event = document.createEvent("MessageEvent");
event.initMessageEvent ("own_message", true, false, data, window.location, 0, window, null);
// you might want to change "own_message" back to "message" or whatever you like
//and there we go
request.dispatchEvent(event);
}
}
And instead of window.postMessage(data) now use Communicator.postMessage(data)
that's all!
Now in my overlay there's nothing but our good old
addEventListener('own_message', someMessageFunc, false, true);
//or maybe even "message" just like originally
Hopefully this will work for you, too (didn't check that on iframes...)
You should check the type of iframe B
Edit:
Apparently you must flag your chrome as contentaccessible, and take into consideration the security.
Just posting in case someone faced the same problem.
Succeeded in posting message from within B to A using events as described here.
But it is not answer, because window.parent.postMessage() still doesn't work as intended.

Is there a way to access an iframe's window object from the canvas in FBJS? (facebook)

From the facebook canvas, I need to be able to access an iframe window. Normally you could do this with window.frames, but FJBS doesn't seem to allow access to the window object.
Has anyone figured out how to access window objects?
you could try this. Let me know how it works.
var myIframe = document.getElementById('myIframeId');
// could retrieve window or document depending on the browser
// (if FBJS allows it!?)
var myIframeWin = myIframe.contentWindow || myIframe.contentDocument;
if( !myIframeWin.document ) { //we've found the document
myIframeWin = myIframeWin.getParentNode(); //FBJS version of parentNode
}
Browsers handle domain security on the principle of Same Origin Policy
And the laws of cross domain communication
Also you will find an interesting read on the creationg of read-write JS APIs on this blog post http://piecesofrakesh.blogspot.com/2007/11/how-to-build-readwrite-javascript-api.html

Categories

Resources