js-cookie library working on Android but not iOS devices - javascript

I am building a web app that uses js-cookie. I use the following to import the js-cookie library into my html/javascript file:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jscookie/2.1.4/js.cookie.js"></script>
My js-cookie code works perfectly with Android devices: Cookies are created and retrieved, just as expected. However, the same code fails to write/read cookies when executed on iOS devices (iPhones). The browser doesn't matter; I have tested with the latest versions of Safari, Chrome, and Firefox for iOS.
The cookies, when written, come back as undefined when I attempt to read them on iOS devices. Here is a snippet of code that I use to write the cookies:
//Set expiration cookie...
nowDate = new Date();
expiresDate = new Date(nowDate.getTime() + (120 * 120000));
//cookie expires in 4 hours
Cookies.set('expires', expiresDate, { expires: expiresDate });
Any subsequent attempt to read these cookies works perfectly on Android devices, but not on iOS devices. Here's an example piece of code I use to read the cookie:
expiresCookie = Cookies.get('expires'); //get expiresCookie
What am I doing wrong?

The browser you use on iOs has no impact because, it's always the Safari engine. On iOs, chrome, firefox and others are just frame around the safari webview. That's for the pro tip.
Now, in your problem. Can you access to the classical cookie API ? You can do it using this :
document.cookie
If no, you have a very big problem. Maybe you've already moved to iOS 11 and be included in the no-more-cookie policy :
http://adage.com/article/digitalnext/ios-11-kill-cookie/311444/
Or maybe you have enabled an ad-block/do-not-track feature.

First, I think you have a trouble with you link to the script. If you did your first tests on android maybe your device still keep this file in your cache.
try with this url for having latest version: https://cdnjs.cloudflare.com/ajax/libs/js-cookie/latest/js.cookie.js
Then, check also that your url is not in file location (file:///.../file.html) instead of http (http://domain/file.html). Browsers doesn't save cookies when there is no domain and no http communication.

Related

document.location.href not working on Safari 2020

I'm having issue redirecting a webpage on all browsers. I created a custom page for a client about a year back on SHOPIFY and now the redirect function no longer works.
I was originally using document.location.href = "/cart" and all worked well. But I recieved a call from him today saying the page wont redirect anymore on his IPhone.
I changed it to window.top.location.href, this fixed it for most browsers except safari. I understand that the best way for this to work on all browsers is the document version. But that seems to have been out dated this year.
setTimeout(function(){ document.location.href = '/cart';},1000);
Checking the user agent of the browser and if it's safari we can do a different tailored version of a redirect, just haven't found out how to do this on the new safari yet.
#stanislav seems to have the same issue from this link, I suspect we will start to see the number of people with this issue growing.
Why isnt window.location.href= not forwarding to page using Safari?
Thanks to all for the input and suggestions, hoping to get the resolved soon.
try upgrade , Safari version 14 fixed this bug.

How can I check if a browser is Chromium-based?

I have a Chrome extension, and I am currently writing a website to advertise it.
I know that a Chrome extension can be installed in all Chromium-based browsers (Chrome, Opera, etc.).
Is it possible to check if a browser can download the extension from the web store or is chromium-based?
I found code to detect if it was Google Chrome here. Correct me if I'm wrong, but I think window.chrome doesn't return in all Chromium-based browsers.
window.chrome
As of now, window.chrome works in all chromium based browsers
var isChromium = !!window.chrome;
console.log(isChromium)
Resources
https://browserstrangeness.github.io/css_hacks.html
http://browserhacks.com/
navigator.userAgentData
User-Agent Client Hints API returns information about the browser and operating system of a user. (Introduced in chrome 90)
var isChromium = !!navigator.userAgentData && navigator.userAgentData.brands.some(data => data.brand == 'Chromium');
console.log(isChromium)
Resources
https://developer.mozilla.org/en-US/docs/Web/API/Navigator/userAgentData
https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData
https://web.dev/migrate-to-ua-ch/
Considering that you just want to get to know whether browser is chromium based or not ,
Method 1: ( Server Side Detection)
-- Get Browser name from client request itself and serving the webpage accordingly. For example, If backend is based on Nodejs, You can get browser name as answered in this answer.
Method 2: ( Client Side Detection)
-- On client Side ,You can first get the Browser Name as answered in this answer , and then check it from HARD-CODED Chromium-based browsers Array.
Try this. This check shows true for Chrome, Safari, Edge, Samsung browser… etc
The -webkit-appearance property is used by WebKit-based (e.g., Safari) and Blink-based (e.g., Chrome, Opera) browsers to achieve the same thing.
function isChromium(){
return window.CSS && window.CSS.supports && window.CSS.supports('(-webkit-appearance:none)');
}
Try using the following expression
navigator.userAgent.includes("Chrome")
I guess:
var isChrome = navigator.userAgent.match(/Chrome\/\d+/) !== null;

$window.location = pdfLocation; not downloading PDF AngularJs

I am receiving the location of a pdf document in angular, and I cant get it to consistently download.
It works on my home laptop, but not whilst at work.
Code below
RenderService.document('document.pdf', spec).then(function(pdfLocation) {
$window.location = pdfLocation;
});
Works in Chrome on Ubuntu at home, not on the same set up at work. Does anyone know any reason why the operation of '$window.location' wouldn't be idempotent?
Update:
Also works on FF on my work machine, just not Chrome
This mostly happends if you have some third part software installed or the browser security is configured as to high. Check for addblocker & antivir software on your machine and also check the security configuration in your browser. Ensure that your pdf location is based on HTTPS if your application is running on HTTPS.
For Chrome & Safari try to set your window.location.href property instead of window.location. This should work for all browser so.
RenderService.document('document.pdf', spec).then(function(pdfLocation) {
window.location.href = pdfLocation;
return false;
});
Here is a plnkr demo which does run well in chrome.
Thanks to #lin I realised the issue was chrome blocking my download due to the advanced security option in Chrome:
"Protect you and your device from dangerous sites"
I'm not sure how to get around it yet, and will update this answer if I find a solution

Angular GET request error, but only on safari iOS

I'm building a website using WordPress as a backend, and AngularJS as the frontend. I'm using the WordPress JSON API to get my data to the front-end.
https://wordpress.org/plugins/json-api/
The problem
I'm using AngularJS to get my data from the WordPress JSON API. I have created the following service:
this.getPage = function ( slug ) {
return $http.get('wordpress/api/get_page/?slug=' + slug)
}
I use this service in my controller to get the current page like this:
HTTPService.getPage('home')
.success(function ( data ) {
$scope.page = data.page;
console.log(arguments);
})
.error( function () {
console.log(arguments);
})
This is working fine in all browsers, except for Safari on iOS. On Safari on iOS I get the following response when I log the error arguments:
This is the safari debugger which showed when I connected my iPhone to my Mac. The error response which I get is error code 0..
What I have tried so far
I have set Access-Control-Allow-Origin "*" in the .htaccess file, but this doesn't seem to work. The request is done on the same domain with a relative URL, so I don't think that this is the problem.
So, does anyone know why this is not working on Safari (iOS)?
EDIT
Some extra information as requested:
I'm pretty sure that this is due to the fact that Safari is the only browser that has the policy of blocking "3rd party cookies and other website data" by default. Actually, this issue shouldn't be exclusive of Safari iOS, it should also happen with Safari on your OSX. I'm pretty sure that if it's not happening in your MacBook is because one day you changed the default settings of the "Privacy".
You can try this, open Safari, go to "preferences" and under the tab "Pricacy" check if you have the option: "Block cookies and other website data" set to "From third parties and advertisers". This is the first, and the default option in the modern versions of Safari.
In your MacBook it will look like this:
And in iOS it will look like this:
Just to confirm that this is in fact what's causing your issue: change this setting to "Never", clear the cache and try to reproduce that problem again. I'm quite confident that you won't be able to reproduce it.
Now, if you set it back to "Block cookies and other website data: From third parties and advertisers" and you first clear the cache, you will have that problem again (with either iOS or OSX). After you've confirmed that this is the cause of your problem, set this setting back to "From third parties and advertisers", so that you can reproduce and address the problem with the default settings.
Bare in mind that every time that you want to re-test this issue you will be better off clearing the cache of Safary. Otherwise it could happen that Safari decides that the site serving the API can be trusted and you won't be able to reproduce the issue. So, just to be sure, clear the cache every time that you test this.
I believe that the root of this problem is that Safari wants to make sure that the user has had a direct interaction with the page that it's serving the "3rd party content" before the main page loads that content.
I would need to know more about your project in order to suggest an "optimal" solution. For instance: will the final app be integrated under the same domain as the API? Because if that's the case, you shouldn't have that issue when you go to production. I mean, if the app that you are developing will be hosted under: http://whatever.yourDomain.org and the API is going to be part of that same domain (yourDomain.org), then you shouldn't have that issue at all in production.
On the other hand, if you need to have have the API hosted under a different domain, then you will have to find a way to "trick" Safari. Have a look at this:
Safari 3rd party cookie iframe trick no longer working?
And this:
http://www.allannienhuis.com/archives/2013/11/03/blocked-3rd-party-session-cookies-in-iframes/
I hope that this helps.

How to detect if web app running standalone on Chrome mobile

Chrome mobile has recently added the ability to add to home screen, similar to iOS. This is cool but it doesn't support it as well as iOS - it doesn't support window.navigator.standalone so you can't detect whether you are running as a standalone app.
The reference says:
How can I detect if the app is running as an installed app?
You can’t, directly.
Notice it says "directly". My question is can we do it indirectly? Is there some tricky way to make an educated guess?
This answer comes with a huge delay, but I post it here just for other people who are struggling to find a solution.
Recently Google has implemented the CSS conditional display-mode: standalone, so there are two possible ways to detect if an app is running standalone:
Using CSS:
#media all and (display-mode: standalone) {
/* Here goes the CSS rules that will only apply if app is running standalone */
}
Using both CSS and Javascript:
function isRunningStandalone() {
return (window.matchMedia('(display-mode: standalone)').matches);
}
...
if (isRunningStandalone()) {
/* This code will be executed if app is running standalone */
}
If you need more information, Google Developers has a page dedicated to this topic: https://developers.google.com/web/updates/2015/10/display-mode
iOS and Chrome WebApp behaves different, thats the reason i came to following:
isInWebAppiOS = (window.navigator.standalone === true);
isInWebAppChrome = (window.matchMedia('(display-mode: standalone)').matches);
Same as here: Detect if iOS is using webapp
For the IOS we have window.navigator.standalone property to check..
But for Chrome on Android, it doesn't support this property. Only way to check this is by calculating screen width and height.
Below is the code to check that:
navigator.standalone = navigator.standalone || (screen.height-document.documentElement.clientHeight<40)
I got reference from below link:
Home Screen Web Apps for Android Thanks to Chrome 31
An old question but significantly better solutions available today for Chrome Android.
One of the ways(cleanest IMO). You may add Web App Manifest with a 'start_url' key with a value that adds a query string parameter to your usual homepage.
ex:- if homepage url is https://www.example.com.
in Web App Manifest set
"start_url": "https://www.example.com/?user_mode=app"
Google's guide about Web app manifest:https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
With IOS, localstorage for the standalone and web mode are different. With android KitKat and Chrome, when you save a value in localstorage on the web version, you're able to retrieve it in standalone mode.
So, you just have to save document.documentElement.clientHeight to localstorage when user is browsing the web version (before adding to homescreen). Then, just compare the current value of document.documentElement.clientHeight with localstorage value. If the current value is >, it's standalone mode.
I tried it on several devices.
For Google Chrome (Android) from version 39 onwards with web application manifest (json) and in case, it is a single page application, I use this 'trick':
In the manifest.json I put: "start_url": "standalone.html".
Normally it is (in my case index.html), but from index.html I make an identical clone: standalone.html (or whatever you fancy).
Then, to check, I use Javascript like this:
var locurl = document.location.href;
if (locurl.indexOf("standalone.html") != -1) {
console.log("app is running standalone");
} else {
console.log("app is running in normal browser mode");
}
That works.
It might work too in Google Chrome (mobile) version 31-38 with this meta-tag:
<meta name="application-url" content="http://my.domain.com/standalone.html">.
Not tested, yet.
There is no 'proper' way to do it on Android, hence no API support yet.
The workaround we used in my company -
On first login, store screenheight in localstorage.
By screenHeight i mean document.documentElement.clientHeight before page loads, since then doc grows and its not accurate measure for real available screen height.
Whenever user logs in next time - check current screenheight vs stored - if it becomes bigger, the user has gone fullscreen.
There is no scenario upon which it can become smaller, IF YOU DO store FIRST TIME value for screen height.
Caveat - user that will clean cash.
We chose to ignore that, since most users don't do it or do it relatively rarely, and it will suffice(in our opinion) for some time until there will be API fix for this( hopefully there will be :) )
Option b - check available screenheight vs device screen height, the matchup for a few test devices & browser modes showed some pattern( available height < 70 in webapp) - i strongly believe a wider comparison can get values that will suffice for 90% of devices in 90% cases.
All of this is a workaround, of course, i m not pretending its a solid stable way to get to desired functionality - but for us it worked, so i hope this helps somebody else who fought this bug(cant call missing such crucial api feature other way). Good luck :)
To detect if it's running on MIT AI2 webview:
if (typeof window.AppInventor!="undefined") { return true; }
you have to work with window.navigator.standalone, this API is only works on mobile IOS safari, not event on your macbook or iMac's safari...

Categories

Resources