js php, ajax remembers previously loaded content - javascript

I have the weird issue, I have been looking for the solution for a while with no result. I'm developing a website, decided to load every subpage(content) dynamically via AJAX(also .js and .css files for each subpage). Now, when I'm working on it and change scripts/css for some file and refresh the page, it doesn't load them. It's like AJAX remembers the previous version, because when I turn it all of and come back after few hours it changes (!). Any ideas for this one? I want to avoid remembering anything by site memory(or anything) so I could work on this normally. I don't use jquery, I use pure js and my own function for ajax connection, maybe I should add there something? Here it is:
function sendQuery( data )
{
var http = new XMLHttpRequest();
var url = data["url"];
var params = "";
var query = data["params"];
for(var key in query)
params+=key+"="+query[key]+"&";
params=params.substring(0,params.length-1);
http.open("POST", url, true);
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");
http.send(params);
http.onreadystatechange = function()
{
if(http.readyState == 4 && http.status == 200)
{
data["result"](http.responseText);
}
}
}

Not sure entirely what you mean, but this sounds like a caching issue, why not append the current time or a similar random string to the request as a separate parameter? This level of uniqueness should prevent the request response from being cached by the browser.
e.g. '?nocache='+new Date().getTime()
You may also want to prevent the server side response from caching the content returned by the call by setting the appropriate headers (e.g.):
response.setHeader( "Pragma", "no-cache" );
response.setHeader( "Cache-Control", "no-cache" );
response.setDateHeader( "Expires", 0 );

It seems highly related with your caching policy.
If you're hosting site with apache,
Check .htaccess in your root directory you might see something like this:
# Set up 2 Hour caching on commonly updated files
<FilesMatch "\.(xml|txt|html|js|css)$">
ExpiresDefault A7200
Header append Cache-Control "proxy-revalidate"
</FilesMatch>
The setting above set expire time to 7200 seconds = 2 hours.
To disable cache under development:
# Force no caching for dynamic files
<FilesMatch "\.(xml|txt|html|js|css)$">
ExpiresActive Off
Header set Cache-Control "private, no-cache, no-store, proxy-revalidate, no-transform"
Header set Pragma "no-cache"
</FilesMatch>
Then it should works properly.
Another way is to change this line:
var url = data["url"];
To:
var url = data["url"]+"&ts="+(new Date().valueOf());
To avoid the cache. Note: it's just pseudo code. "?" Should be handled if there hasn't one.
Hope it helps :)

Related

Is there a way to access nginx.var in javascript

I have some nginx variables defied in my server_content.conf file is there a way we can access it in my .js file?
servercontent.conf
...
set $debug_log 'off';
...
logging.js
if(ngx.var.debug_log = 'on')
.. do something
Using the SSI
The first way of how this can be solved is to use the Server Side Includes module.
Here is a brief example:
nginx configuration fragment:
set $debug_log on;
location / {
ssi on;
ssi_types application/javascript;
...
}
logging.js example
var logging = '<!--# echo var="debug_log" -->';
console.log("Debug status detected via SSI substitution is", logging);
Read the module documentation to find out all the available features.
For the security purposes, if there is the only JS file you want to be able to receive some data from nginx, declare an individual location for this file (this will also speed-up all the other JS content being served), for example if its URI is /js/logging.js:
location / {
... # default location
}
location = /js/logging.js {
# do not cache this file at the client side
add_header Cache-Control "no-cache, no-store, must-revalidate";
ssi on;
ssi_types application/javascript;
}
Using the AJAX endpoint
The second way to solve this is to define an AJAX endpoint with the nginx configuration:
location = /getdebug {
default_type application/json;
return 200 '{"logging":"$debug_log"}';
}
Now the $debug_log nginx value can be acquired using the AJAX call from the browser-side JavaScript code:
const xhr = new XMLHttpRequest();
xhr.open('GET', '/getdebug');
xhr.responseType = 'json';
xhr.onload = function() {
if (this.status == 200) {
console.log('Debug status detected via AJAX request is', this.response.logging);
}
};
Update 1
Turns out the whole question was about njs rather than browser-side JavaScript. In theory this can be achieved via the subrequests API using responseBuffer or even responseText subrequest object properties. You can look at the Setting nginx var as a result of async operation examples, especially this one, using some kind of more simple plain text endpoint:
location = /getdebug {
default_type text/plain;
return 200 $debug_log;
}
Unfortunately I'm not familiar with the njs (I use the lua-nginx-module for the similar purposes) and don't know if there is a more straight way to do it (which is probably exists).
Additionally, if you are trying to use Node modules with njs, make sure you read the Using node modules with njs documentation chapter.
Update 2
All nginx variables (which are evaluated on per-request basis) are available in the njs code via r.variables{} HTTP Request object property, e.g.
if (r.variables.debug_log == 'on') {
... do something
}

How to trigger Spinner for file download or How to download file in browser if AngularJS $resource response received as an attachement with file name

I'm able to download successfully using below line of code in AngularJS controller.
$window.location.href =$rootScope.urlBase+'/dios/download/lineitemexcel/'+$routeParams.id
But, when data is large and it is taking longer time, for this reason I need to enable angular-Spinner. No way I could find a way to start spinner before the call and it should finish after file download finished in the browser.
Root Problem: How can I enable spinner with existing plugin in the project angular-spinner or usSpinnerService? if this has a solution I dont have next question.
To Solve this problem, I have gone through existing spinner working flow.
Spinner is working if there is $resource call.
Hence above url I tried by forming factory call like below:
Service:
factory('Dios', ['$resource','$rootScope',
function($resource, $rootScope){
return $resource($rootScope.urlBase+'/dios/:id/:status/:third/:fourth/:fifth/:pageNo', {}, {
get: {
method: 'GET'
},
update: {
method: 'PUT'
},
getexcel: {
method: 'GET',
transformResponse: function(data, headers,status){
var dataTransformed = {};
dataTransformed.data=data;
dataTransformed.headers=headers;
dataTransformed.status=status;
return dataTransformed;
}
}
});
}])
Controller:
Dios.getexcel({dios:'dios',third:'download',fourth:'lineitemexcel',fifth: $routeParams.id},function(data){
console.log(data);
]);
Using above factory call rest call with an Id of an Object. That Object I need to retrieve and process using Apache POI JAVA library , and Apache POI library will return as an attachement with response header properties in dev tools network tab as follows:
HTTP/1.1 200
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Access-Control-Allow-Origin: http://10.218.39.45:9000
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: POST, GET, PUT, OPTIONS, DELETE
Access-Control-Allow-Headers: Content-Type,X-Requested With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers
Access-Control-Expose-Headers:
1,Access-Control-Allow-Origin,Access-Control-Allow-Credentials
Content-Disposition: attachment;
filename=LineItems-of_IO-1553-8531Testing_2018-09-18.xlsx
Content-Type: application/vnd.ms-excel
Transfer-Encoding: chunked
Date: Tue, 18 Sep 2018 08:33:46 GMT
In this way I'm able to get spinner but , I am not sure how to download response received as file with specified name in response headers.
using transformResponse: I am expecting responseheaders info, but it is not getting attached to headers in transformResponse:.
So Kindly help me to get spinner is getting triggered for window.location.href=url or help me how download the received data through $resource.
First this question has nothing to do with angularjs itself, this is pure js problem.
For download there are 2 options:
Download file using Ajax and then store it on disk using createObjectURL.
Download file usual way i.e. simple href.
These two are really different:
-1st wont work in some browsers
-1st gives you full access over request, you can comfortably handle errors etc.
-2nd start download in parallel, e.g. in chrome you can close tab with app, but download will still proceed
In 1st way showing spinner is relatively easy, you do it as for any other request.
In 2nd way you usually do not want to show spinner when download is in progress as browser will show progress for you. However, before download starts - before response came from server you sometimes may want to show some waiting and the only way this can be done is using cookies:
you add some param to download request e.g. my-cookie-id=cookie_123
server sets cookie cookie_123 in response
after link is clicked you check for this cookie value (e.g each 100ms)
when you see this cookie value, your file is started to download
I don't see any way to show spinner while downloading file directly using window.location.
But downloading file from response can be possible.
Can you please try below approach?
Delete trasnformResponse from $resource
Write a function to download file
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
$scope.downloadFile= function(data, fileName, contentType) {
var blob = new Blob([data], {
type: contentType
});
var url = URL.createObjectURL(blob);
a.href = url;
a.download = fileName;
a.click();
//hide spinner here
window.URL.revokeObjectURL(url);
}
Change you function call as
Dios.getexcel({dios:'dios',third:'download',fourth:'lineitemexcel',fifth: $routeParams.id},function(data, responseHeader){
$scope.downloadFile(data, responseHeader()['Content-Disposition'].split('filename=')[1] , responseHeader()['Content-Type']);
]);

How to get HTTP header from Javascript?

I have a Tomcat server that only serves static files(html, css, js). When the request comes in it gets intercepted by a proxy server. Proxy server authenticates the user and adds a userId field to the header and forwards it my Tomcat server.
How can I access userId that has been stored in the header from javascript?
Thank you
You can't, BUT...
If such header is send to the browser you could make an ajax request and get that value from it.
This little javascript could be useful in your case. Watch out, use it with caution and sanitize or change the URL depending on your needs, this is just a "concept", not a copy-paste solution for every case. In many other cases this is not a valid solution, cause it is not the header of the loaded document, but another request. Anyway the server, content-type, etc can be use quite safely.
xmlhttp = new XMLHttpRequest();
xmlhttp.open("HEAD", document.URL ,true);
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4) {
console.log(xmlhttp.getAllResponseHeaders());
}
}
xmlhttp.send();
EDIT: Ooops, seem already anwser that part also... Accessing the web page's HTTP Headers in JavaScript
Didn't read it all.
Use below script for access userId
var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
headers = req.getAllResponseHeaders().split("\n")
.map(x=>x.split(/: */,2))
.filter(x=>x[0])
.reduce((ac, x)=>{ac[x[0]] = x[1];return ac;}, {});
console.log(headers.userId);

Prevent browser from caching AJAX requests

I've setup an app and it works fantastic on Opera and Firefox, but on Google Chrome it caches the AJAX request and will give stale data!
http://gapps.qk.com.au is the app. When ran in Chrome it doesn't even send the AJAX requests, but when tried in another browser it always does the AJAX request and returns data.
Is there any method (Apache/PHP/HTML/JS) to stop Chrome from doing this behavior?
The AJAX call:
function sendAjax(action,domain,idelement) {
//Create the variables
var xmlhttp,
tmp,
params = "action=" + action
+ "&domain=" + encodeURIComponent(domain)
xmlhttp = new XMLHttpRequest();
//Check to see if AJAX request has been sent
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
$('#'+idelement).html(xmlhttp.responseText);
}
};
xmlhttp.open("GET", "ajax.php?"+params, true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
//console.log(params);
xmlhttp.send(params);
}
sendAjax('gapps','example.com','gapps');
The browser cache behaves differently on different settings. You should not depend on user settings or the user's browser. It's possible to make the browser ignore headers also.
There are two ways to prevent caching.
--> Change AJAX request to POST. Browsers don't cache POST requests.
--> Better Way & good way: add an additional parameter to your request with either the current time stamp or any other unique number.
params = "action=" + action
+ "&domain=" + encodeURIComponent(domain)
+ "&preventCache="+new Date();
Another alternative to the Javascript solution is to use custom headers:
In PHP it would look like this:
<?php
header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");//Dont cache
header("Pragma: no-cache");//Dont cache
header("Expires: Thu, 19 Nov 1981 08:52:00 GMT");//Make sure it expired in the past (this can be overkill)
?>
I was using jQuery ajax request when I ran into this problem.
According to jQuery API adding "cache: false" adds a timestamp like explained in the accepted answer:
This only works with GET and HEAD requests though but if you're using POST the browser doesn't cache your ajax request anyways. There's a but for IE8, check it out in the link if needed.
$.ajax({
type: "GET",
cache: false,
});
Below line of code worked for me.
$.ajaxSetup({ cache: false });

Check if third-party cookies are enabled

I have an application that needs to check whether the client browser has third-party-cookies enabled. Does anyone know how to do this in JavaScript?
Technical Background
The third party sets & reads cookies over HTTP (not in JavaScript).
So we need two requests to an external domain to test if third-party cookies are enabled:
One where the third party sets the cookie(s)
The second, with a differing response depending on whether the browser sent the cookie(s) back to the same third party in a second request.
We cannot use XMLHTTPRequest (Ajax) because of the DOM security model.
Obviously you can't load both scripts in parallel, or the second request may be made before the first request’s response makes it back, and the test cookie(s) will not have been set.
Code Example
Given:
The .html file is on one domain, and
The .js.php files are on a second domain, we have:
The HTML test page
Saved as third-party-cookies.html
<!DOCTYPE html>
<html>
<head id="head">
<meta charset=utf-8 />
<title>Test if Third-Party Cookies are Enabled</title>
<style type="text/css">
body {
color: black;
background: white none;
}
.error {
color: #c00;
}
.loading {
color: #888;
}
.hidden {
display: none;
}
</style>
<script type="text/javascript">
window._3rd_party_test_step1_loaded = function(){
// At this point, a third-party domain has now attempted to set a cookie (if all went to plan!)
var step2Url = 'http://third-party.example.com/step2.js.php',
resultsEl = document.getElementById('3rd_party_cookie_test_results'),
step2El = document.createElement('script');
// Update loading / results message
resultsEl.innerHTML = 'Stage one complete, loading stage 2…';
// And load the second part of the test (reading the cookie)
step2El.setAttribute('src', step2Url);
resultsEl.appendChild(step2El);
}
window._3rd_party_test_step2_loaded = function(cookieSuccess){
var resultsEl = document.getElementById('3rd_party_cookie_test_results'),
errorEl = document.getElementById('3rd_party_cookie_test_error');
// Show message
resultsEl.innerHTML = (cookieSuccess ? 'Third party cookies are <b>functioning</b> in your browser.' : 'Third party cookies appear to be <b>disabled</b>.');
// Done, so remove loading class
resultsEl.className = resultsEl.className.replace(/\bloading\b/,' ');
// And remove error message
errorEl.className = 'hidden';
}
</script>
</head>
<body id="thebody">
<h1>Test if Third-Party Cookies are Enabled</h1>
<p id="3rd_party_cookie_test_results" class='loading'>Testing…</p>
<p id="3rd_party_cookie_test_error" class="error hidden">(If this message persists, the test could not be completed; we could not reach the third-party to test, or another error occurred.)</p>
<script type="text/javascript">
window.setTimeout(function(){
var errorEl = document.getElementById('3rd_party_cookie_test_error');
if(errorEl.className.match(/\berror\b/)) {
// Show error message
errorEl.className = errorEl.className.replace(/\bhidden\b/,' ');
} else {
}
}, 7*1000); // 7 sec timeout
</script>
<script type="text/javascript" src="http://third-party.example.com/step1.js.php"></script>
</body>
</html>
The first third-party JavaScript file
Saved as step1.js.php
This is written in PHP so we can set cookies as the file loads. (It could, of course, be written in any language, or even done in server config files.)
<?php
header('Content-Type: application/javascript; charset=UTF-8');
// Set test cookie
setcookie('third_party_c_t', 'hey there!', time() + 3600*24*2);
?>
window._3rd_party_test_step1_loaded();
The second third-party JavaScript file
Saved as step2.js.php
This is written in PHP so we can read cookies, server-side, before we respond. We also clear the cookie so the test can be repeated (if you want to mess around with browser settings and re-try).
<?php
header('Content-Type: application/javascript; charset=UTF-8');
// Read test cookie, if there
$cookie_received = (isset($_COOKIE['third_party_c_t']) && $_COOKIE['third_party_c_t'] == 'hey there!');
// And clear it so the user can test it again
setcookie('third_party_c_t', '', time() - 3600*24);
?>
window._3rd_party_test_step2_loaded(<?php echo ($cookie_received ? 'true' : 'false'); ?>);
The last line uses the ternary operator to output a literal Javascript true or false depending on whether the test cookie was present.
Test it here.
Available for your testing pleasure at https://alanhogan.github.io/web-experiments/3rd/third-party-cookies.html.
(As a final note — don’t use someone else’s server to test third-party cookies without their permission. It could break spontaneously or inject malware. And it’s rude.)
Here's a pure JS solution not requiring any server-side code, so it can work from a static CDN: https://github.com/mindmup/3rdpartycookiecheck - the first script sets the cookie in the code, then redirects to a second script that will post a message to the parent window.
You can try out a live version using https://jsfiddle.net/tugawg8y/.
Note, this demo does not seem to work any more. Maybe the window.postMessage call is being blocked.
client-side HTML:
third party cookies are <span id="result"/>
<iframe src="https://mindmup.github.io/3rdpartycookiecheck/start.html"
style="display:none" />
client-side JS:
var receiveMessage = function (evt) {
if (evt.data === 'MM:3PCunsupported') {
document.getElementById('result').innerHTML = 'not supported';
} else if (evt.data === 'MM:3PCsupported') {
document.getElementById('result').innerHTML = 'supported';
}
};
window.addEventListener("message", receiveMessage, false);
Of course, this requires that the client runs JavaScript which is a downside compared to the server-based solutions; on the other hand, it's simpler, and you were asking about a JS solution.
Alan H's solution is great, but you don't have to use PHP or any other server-side programming language.
At least if you use nginx. :)
This is a pure* nginx server-side configuration for Alan's solution:
server {
listen 80;
server_name third-party.example.com
# Don't allow user's browser to cache these replies
expires -1;
add_header Cache-Control "private";
etag off;
# The first third-party "JavaScript file" - served by nginx
location = /step1.js.php {
add_header Content-Type 'application/javascript; charset=UTF-8';
add_header Set-Cookie "third_party_c_t=hey there!;Max-Age=172800";
return 200 'window._3rd_party_test_step1_loaded();';
}
# The second third-party "JavaScript file" - served by nginx
location = /step2.js.php {
add_header Content-Type 'application/javascript; charset=UTF-8';
set $test 'false';
if ($cookie_third_party_c_t = 'hey there!') {
set $test 'true';
# clear the cookie
add_header Set-Cookie "third_party_c_t=;expires=Thu, 01 Jan 1970 00:00:00 GMT";
}
return 200 'window._3rd_party_test_step2_loaded($test);';
}
}
Side notes:
Yeah, yeah, I know that IfIsEvil,
I kept the names ending with ".php" for complete compatibility with Alan's "The HTML test page" (third-party-cookies.html),
You can also move the common "setting the Content-Type header" line of both locations to the server section (scope) of the config - I kept it like this to make it more like Alan H's solution.
My solution works by loading a <script> from an external domain that sets a cookie, checks if it was successful, and then passes the result (1 or 0) as an argument to a callback function.
The HTML:
<script>
function myCallback(is_enabled) {
if (is_enabled===1) {//third party cookies are enabled
}
}
</script>
<script src="https://third-party-domain/third-party-cookies.php?callback=myCallback"></script>
If you prefer to run it asynchronously, you may use the async and defer attributes.
This also works with jQuery:
<script>
$.ajax({
url: 'https://third-party-domain/third-party-cookies.php',
dataType: 'jsonp',
}).done(function(is_enabled) {
if (is_enabled===1) {//third party cookies are enabled
}
})
</script>
Here is the third-party-cookies.php code. This must be hosted on a different domain. The server must support PHP:
<?php
header('Cache-Control: no-store');
header('Content-Type: text/javascript');
if ($_GET['callback']=='') {
echo 'alert("Error: A callback function must be specified.")';
}
elseif (!isset($_GET['cookieName'])) {// Cookie not set yet
$cookieName = strtr((string)$_SERVER['UNIQUE_ID'], '#', '_');
while (isset($_COOKIE[$cookieName]) || $cookieName=='') {
$cookieName = dechex(mt_rand());// Get random cookie name
}
setcookie($cookieName, '3rd-party', 0, '/');
header('Location: '.$_SERVER['REQUEST_URI'].'&cookieName='.$cookieName);
}
elseif ($_COOKIE[$_GET['cookieName']]=='3rd-party') {// Third party cookies are enabled.
setcookie($_GET['cookieName'], '', -1, '/'); // delete cookie
echo $_GET['callback'].'(1)';
}
else {// Third party cookies are not enabled.
echo $_GET['callback'].'(0)';
}
In theory you'd just have a page call out somewhere that would set a thirdparty cookie and then check for that cookie's existence. However, standard browser security does not allow scripts from domain A to do anything with cookies set on domains B,C,etc... e.g. you can't access "foreign" cookies.
If you have some specific usage in mind, such as checking if ads are blocked (which would also block the 3rd party tracking cookie), you could check if the ad server's content is within the page's DOM, but you couldn't see if the cookie's there.
Third Party Cookie detection with Whitelisting of URLs
Alan H & Gojko Adzic are good enough for majority of use cases, but these solutions won't work if you want your users to do whitelisting of third party cookies only to certain domains.
I'm presenting a slightly modified version of Gojko Adzic's answer
For this we need two domains :
Domain 1, this is the page your user lands, it initially sets tpc=pending, then it redirects to Domain 2
Domain 2 injects Domain 1's url in an iFrame, tries to set a cookie tpc=true and redirects back to Domain 1
Now, Domain 1 reads the cookie tpc and checks if its true, if we get value as true, third party cookies are allowed if it is still in pending third party cookies are blocked blocked.
Now, you might ask your users to whitelist (allow third party cookies) ONLY for Domain 1, also by this technique third party detection will be accurate if the users had white listed your domain.
This is tested in Chrome 74, 75, 76 & Edge 78
Unfortunately, Mozilla doesn't provide whitelisting of urls like Chrome does and Safari has it own mechanisms of detecting third party cookies (ITP).
P.S. Will upload this demo in my github when I get time.
This is something that I did to check if third-parties cookies have been blocked by the user.
I just try to access the browser's local storage. If the user has enabled third-party cookies then it should be available, else it would throw an error.
try {
if(window.localStorage) {
//cookies enabled
}
} catch (err) {
//cookies disabled
}
Steps to check if third party cookies are enabled with Greg and Alan's solutions:
I modify the files as my only need was to check if third party cookies are enabled or not, depends on that i would do something like route them to a page telling users to enable third party cookies.
1) Edit your nginx sites config
(In debian 9 is in /etc/nginx/sites-enabled/default)
$ sudo nano /etc/nginx/sites-enabled/default
You'll need to have TLS/SSL on your domain or else you won't be able to set cookies from a third party domain and you'll get an error saying:
Because a cookie’s SameSite attribute was not set or is invalid, it defaults to SameSite=Lax, which prevents the cookie from being sent in a cross-site request. This behavior protects user data from accidentally leaking to third parties and cross-site request forgery. Resolve this issue by updating the attributes of the cookie: Specify SameSite=None and Secure if the cookie should be sent in cross-site requests. This enables third-party use. Specify SameSite=Strict or SameSite=Lax if the cookie should not be sent in cross-site requests.
Specify your allowed domains in "Access-Control-Allow-Origin", not recomended to leave it with "*" (public access).
You can specify 'Access-Control-Allow-Methods "GET";' as is the only method being used.
(I set those headers with "*" (public) just to make sure it works, after that, you can edit them.)
You can change the name of the endpoints (step1.js.php & step2.js.php) but you'll need to change it in you js script. (Requests are made to your-custom-domain.com/step1.js.php o your-custom-domain.com/step2.js.php unless you change it. The extension does not really matter, you can change it for "step1" and "step2" or whatever you like)
# Nginx config start
server {
server_name your-custom-domain.com;
# Check if third party cookies are allowed
# The first third-party "JavaScript file" - served by nginx
location = /step1.js.php {
expires -1;
add_header Cache-Control "private";
etag off;
add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Methods "*";
add_header Content-Type 'application/javascript; charset=UTF-8';
add_header Set-Cookie "third_party_c_t=hey there!;Max-Age=172000; Secure; SameSite=none";
return 200 'window._3rd_party_test_step1_loaded();';
}
# The second third-party "JavaScript file" - served by nginx
location = /step2.js.php {
add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Methods "*";
add_header Content-Type 'application/javascript; charset=UTF-8';
set $test 'false';
if ($cookie_third_party_c_t = 'hey there!') {
set $test 'true';
# clear the cookie
add_header Set-Cookie "third_party_c_t=;expires=Thu, 01 Jan 1970 00:00:00 GMT; Secure; SameSite=none";
}
return 200 'window._3rd_party_test_step2_loaded($test);';
}
# managed by Certbot, here is where your certificates goes.
listen [::]:443 ssl ipv6only=on;
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/www.couchdb.me/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/www.couchdb.me/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
Save it (ctrl+x - Press letter Y if you want to save it - Enter to confirm) and restart/reload your nginx:
$ sudo systemctl restart nginx.service
2) In your landing page (different from your-custom-domain.com)
You can change the name of the methods (_3rd_party_test_step1_loaded and _3rd_party_test_step2_loaded) but you'll need to change it also in nginx's config. (Make sure names are unique)
2.1) Add this cript to the header of your html (this must be loaded first):
<script type="text/javascript">
window._3rd_party_test_step1_loaded = function () {
// At this point, a third-party domain has now attempted to set a cookie (if all went to plan!)
var step2El = document.createElement("script");
const url = your-custom-domain.com + "/step2.js.php";
step2El.setAttribute("src", url);
document.head.appendChild(step2El);
};
window._3rd_party_test_step2_loaded = function (cookieSuccess) {
// If true, the third-party domain cookies are enabled
// If false, the third-party domain cookies are disable
cookieSuccess ? callMethodIfTrue() : callMethodIfFalse();
};
</script>
2.2) Add the script at the end of your body html:
<script type="text/javascript" src="https://your-custom-domain/step1.js.php"></script>
or if your are working in a js file (remember that you need to have your file added on your html landing page eg:
<script type="text/javascript" src="path/to/your/js/file"></script>
JS file:
window._3rd_party_test_step1_loaded = function () {
// At this point, a third-party domain has now attempted to set a cookie (if all went to plan!)
var step2El = document.createElement("script");
const url = that.$url + "/step2.js.php";
step2El.setAttribute("src", url);
document.head.appendChild(step2El);
};
window._3rd_party_test_step2_loaded = function (cookieSuccess) {
// If true, the third-party domain cookies are enabled
// If false, the third-party domain cookies are disable
cookieSuccess ? callMethodIfTrue() : callMethodIfFalse();
};
window.onload = function () {
const url = "your-custom-domain.com" + "/step1.js.php";
var step1El = document.createElement("script");
step1El.setAttribute("src", url);
document.body.appendChild(step1El);
};

Categories

Resources