I am making a html5 web app based on an existing ios app. It targets most recent two versions of ios Safari browser. For this web app to work, I need to use an api that handles communication between current ios app and php backend.
The very first hurdle is that api config files (gzipped) needs to be downloaded from server on a regular basis (for example each time app starts) to keep itself updated. Then I need to unzip to get config files, which basically contains key-value pairs of command name and http address. When I need certain command, e.g. display a user's profile pic, I lookup the config files by command number to find the corresponding request address so that I could make request to server.
To summerize the steps:
Download (gziped) configuration files by ajax
I don't think html anchor tag (with or without download attribute) is an option. Because in that way Safari will prompt user to open the downloaded file using file handling apps (e.g. FilesApp). The download must happen in the dark.
Unzip the downloaded file
I know a few js library promise to do this work. I haven't tested them yet for step one is not solved. Any recommandatio is welcomed.
Lookup http address in those files whenever making a api call
It should be no problem though.
For ios app, I can simply download the config files into app sandbox and do whatever I want with it. But for web app, even newest ios Safari don't suppor HTML5 file system api. What can I do?
Step 1.
Safari should support HTTP compression. Your best best is to leverage this, as opposed to figuring out a way to unzip a file using JavaScript. It looks like there are a few options with PHP:
http://php.net/manual/en/zlib.configuration.php
http://php.net/manual/en/function.ob-gzhandler.php
Or even at the server level:
http://httpd.apache.org/docs/2.2/mod/mod_deflate.html
Step 2.
Use sessionStorage to cache the configuration settings. The data will be cleared out each time a user closes their browser.
Step 3.
The PHP handler that is called by the AJAX request should take care of parsing the config files and send JavaScript-friendly JSON to the browser. Use JSON.parse() and JSON.stringify() to serialize/de-serialize data as you read/save to sessionStorage.
Related
I want copy all files in a web directory on a webserver, and ideally in its component subdirectories, into local device storage for Android and iOS in Cordova using javascript and/or cordova plugins.
The use case is to copy an entire (smallish) webapp/page from a remote webserver (that we control, and where we posted the content) into local storage on the device. This will be used for a form of hot code push for a cordova app.
It's possible to copy files using cordova-plugin-file-transfer:
https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/
or in a more standards-compliant way using XMLHttpRequest (XHR):
https://cordova.apache.org/blog/2017/10/18/from-filetransfer-to-xhr2.html
How does one copy an entire directory tree, overwriting an existing one, in device storage.
Preferable: method to include error handling for the case that something prevents the full copy from happening, possibly resulting in a partial copy or a corrupted directory.
Is there an api or combination of apis that do this already? If not, does someone have or know of code to accomplish this?
Thanks!
You can look at hydration of phonegap for hot push :
http://docs.phonegap.com/phonegap-build/tools/hydration/
I think it may be suitable for your need.
However, be very careful with hot code push because apple doesn't like it very much and it's rather contrary to their guideline.
We have a large number of people (10k+) who return to my clients' sites on a regular basis to use a web app we built, improve, and host for them. We have been making fairly frequent backward-incompatible updates to the web app's javascript as our app has improved and evolved. During deployments, the javascript is minified and concatenated into one file, loaded in the browser by require.js, and is uploaded to and hosted on Amazon S3. The file name & url currently doesn't change at all during updates. This last week we deployed a major refactor to the web app and got a few (but not a lot) of reports back that the app stopped working for some people, particularly in firefox. It seemed like a caching issue. We were able to see it initially in a few browsers in testing but it seemed to go away after a refresh or two.
It dawned on me that I really don't know what browser-caching ramifications deploying a new version of a javascript file (with the same name) on S3 will have and whether this situation warrants cache-busting or manipulating S3's headers or anything. Can someone help me get a handle on this? Are there actions I should be taking during deployments to ensure that browsers will immediately get the new version of a javascript file? If not, we run the risk of the javascript and the server API being out of sync and failing, which I think happened here.
Not sure if it matters, but the site's server runs Django and the app and DB are deployed to Heroku. Static files are deployed to S3 using S3Boto via Django's collectstatic command.
This depends a lot on the behaviour of S3 and the headers it sends when requesting files on S3. As you experienced, browsers will show different caching behaviour - so the best option is to use unique filenames.
I would suggest to use cachebuster hashes - in this way you can be sure that the new file always gets requested by browsers and you can use long cache-lifetime headers if you host the files on your own server.
You can for example create a MD5 hash of your minified file and append it (like mycss-322242fadcd23.css). Or you could use the revision number of your source control system. You have to use the cache buster in all links to this file, but you can normally easily do this in your templates where you embed your static resources. Depending on your application, you could probably use this Django plugin that should do this work for you.
I'm trying to fix a tricky JavaScript issue in a Liferay portlet (that also happens to run a large Flex app) and every time I make a change, I have to go back to the prompt and do an "ant deploy" on the portlet, then wait for it to deploy, then reload the page, then wait for the Flex app to load. Every time I try any minor change it takes 3-4 minutes for this whole process.
Is there a configuration or setting that will uncompress the JavaScript and allow me to directly edit the JS files on the server without re-deploying every time? I've read up some on "Developer Mode" but it doesn't seem to be working, and all the Liferay docs seem specific to Tomcat whereas I'm using JBoss.
If you are deploying a war file, just explode it in place (in the jboss deploy directory), so rather than having one compressed file called FlexPort.war, you would have a directory called FlexPort.war which would have all the exploded content from the original WAR file.
If you update JavaScript files, you might need to clear your cache in the browser, but otherwise it should take effect right away. If you update classes, you can cause a fast re-deploy by touch-ing the WAR/web-inf/web.xml file.
===========================================================
Not sure why you're not seeing the JS update, but try reproducing this sequence. It helps to have some browser tool like Firebug or Fiddler installed so you can see the response headers.
Retrieve the JS file directly into your browser. e.g. http://localhost:8080/js/admin/jquery-ui-1.8.12.custom.min.js
Make note of the Last-Modified response header.
Modify the JS file and save. (Make sure the filesystem timestamp of the file has changed)
Retrieve the JS file again. The Last-Modified response header should be incremented to the same value as the timestamp as the filesystem timestamp.
Make sure the HTTP response code is 200 and not 304 (Not Modified).
If you are still seeing the same timestamp after the file modification:
It could be browser caching (See 304 comment above)
I suppose Liferay might be caching all the content, so changes on the file system will not take effect until you redeploy the WAR. If this is the case, try *touch*ing the myportlet.war/WEB-INF/web.xml file which will cause the WAR to be redeployed. Not as efficient, but hopefully faster than reissuing the ant command.
A quickie google revealed this link about Liferay Static Content Caching. It seems Liferay may indeed be caching all this stuff in ehcache. If this is the case with your portlet app, you have 2 choices:
Turn off caching (in dev only, of course) by setting this property in your portal-ext.properties: com.liferay.portal.servlet.filters.cache.CacheFilter=false
If Liferay registers the JMX interfaces for ehcache, you may be able to surgically remove the target items from cache through JMX-Console or twiddle. With either one, once you figure out the exact operation, you can create a batch file to execute it on demand on the command line.
Exploding the war file didn't work out for me. I get around this problem by using a node.js script(an http static file server). What I do is when editing the JS I copy this script to the javascript folder inside the portlet project and fire up the server(You need to install node.js on your dev machine). Then I change the references of my JS scripts in the portlet to point to static server urls.
Eg:- In your liferay-portlet.xml,
<footer-portlet-javascript>/js/app.js</footer-portlet-javascript>
Changes to,
<footer-portlet-javascript>http://localhost:8888/app.js</footer-portlet-javascript>
After that I can just edit the files and view changes in the browser right away.
(You also have to set Access-Control-Allow-Origin header in the static file server)
In my asp page, I have to open a csv file in IE by java script. The code which I am using is as below:
csvWindow = window.open("/com/csv/"+csvFileName, "datacsv", "toolbar=yes,location=no,directories=yes,status=no,menubar=yes,scrollbars=yes,resizable=yes,width=790,height=450,screenX=50,screenY=25,left=50,top=25");
Code is running in IIS server.
When I run this code and open csv file it gives below message
Microsoft Office Excel cannot access the file
"http://192.168.3.228:107/com/csv/CSV_file_1345728.csv". There are several possible reasons:
The file name or path does not exist
the file is being used by another program
the workbook you are trying yo save has the same name as a currently open workbook.
But file is being created.So path is correct and i think that file is also not used by another program
Please help me what should I do
The problem is that when Excel is opened it will attempt to fetch the CSV file itself, this a change in behaviour in office apps since 2007. However since Excel runs in a different process it will not send any cookies that would have been generated during the logon. When the website receives the request it will respond with a 401 status.
There are no easy solutions that I know of with entirely satisfactory results. Here are a number of solutions but all have drawbacks.
Make the authentication cookie persistent, this will allow Offices apps to pick up and send the cookie. The down side being the user remains persistently logged even after a client machine reboot (much like how Stackoverflow appears to work).
Use a standard HTTP authentication protocol like "Basic" or "Negotiate". The down side is that this will cause Excel to display a logon box and the user has to logon again. One exception to this drawback is using "Negotiate" or "NTLM" against an IIS box where the site is registered as part of the IE's Intranet Zone, in which case the HTTP stack used by excel will attempt to use the current user credentials.
Have a server side script that can run anonymously send the csv file and include in the URL some unique ID (such as GUID) which is a one off grant of access. Much more complex to set up.
If you want to open the file with MS Excel, you could try not to serve the file directly, but write an ASP page with Content-Type=application/force-download, the real file name ending with .css and the actual file content. In this case, MSIE will first download the file to the local disk cache and then will feed it to MS Excel.
If you just want to show the CSV text in the browser window, maybe the best is to change its extension or to make some proxy page with Content-Type=text/plain and no mention of CSV at all. The association CSV/Excel seems to be hardcoded in MSIE.
Problem definition:
Server is an embedded system with no access to Internet.
Each server is managed by web interface which uses JavaScript.
Each server has a local copy of JQuery library.
Clients (browsers) are connected to embedded systems (servers) via a very slow connection.
Clients have the latest browsers (HTML5, CSS3, JavaScript 1.8.5)
Clients are not connected to Internet either.
Clients can't access multiple servers at the same time (servers are in distant locations and most probably a client can only access one server and nothing else, but later that day the client may go to another location and connect to another server).
Each server has an IP address (not necessarily in the same range) and no DNS name.
Every time the client connects to an embedded server, it fetches all the files including the huge JQuery library (huge=~90KB)
Question:
The JQuery library is too big for this slow connection but one-time download is acceptable. However, we don't want the clients to download it every time they connect to each new server. The JQuery on all these devices is the same. But apparently the browser cache is domain based. How can we cache the JQuery library so that the client doesn't have to download the JQuery every time it connects to a new server?
just link to it in one place...
for example, if you have a single server, http://1.2.3.4/ that you want to designate as your CDN, put jQuery on it, and link to it in your scripts using <script src="http://1.2.3.4/jquery.min.js"></script>
you could link it to the ip in your link tag. The server does not have to have access to that access or anything, and so all the clients will geht the jquery from the same server all the time and so it is cached.
Here is a simple solution: All your customers must edit their /etc/hosts file (Google for where you can find it on Windows) and put a line like this in their config:
1.2.3.4 jquery-from-closest-server.com
Each client must figure out the closest server which has jQuery and replace 1.2.3.4 with its IP address.
In your HTML code, always use the link http://jquery-from-closest-server.com/jquery.js
To be safe, you may want to register jquery-from-closest-server.com for those customers which do have Internet access.
When the browser asks for the file, it will use /etc/hosts to resolve the IP address. Since the domain name will be the same for all your embedded devices (changes in the IP address are ignored by the browser), the script will be downloaded once for all clients.
Note that this means you can never upgrade to a newer version of jQuery. The problem is that you'd have to replace it on all embedded devices at the same time because there is no telling from which server the customers are downloading it from.
If that bothers you (and it will in about four months after you discovered the first serious bug), here is another solution: Instead of serving the HTML from your embedded device, distribute a static web app (a set of HTML files and JavaScript) which customer can install in their desktop. Use AJAX and iframes to replace parts of the static web app with data from your embedded device.
Advantages:
very fast (no downloads at all)
only little code on the embedded device
easy upgrade strategy
No deadlocks when you need to upgrade either the embedded devices or your controller app.
[EDIT] PS: Consider to compress jQuery with gzip. That leaves you with a 33KB file. All HTML5 browsers can decode compressed files, you just have to tell them by setting the necessary HTTP headers.
Apparently there is no standard way to include JQuery in our project so we chose to replace JQuery with a smaller similar library. These are the options:
JQuery mobile is a better fit for our project since it has a smaller size and can do almost everything we need from JQuery.
Zepto.js is also another suitable replacement.
JQuip is a stripped down version of JQuery that can help our specific project.