I believe this is an Apache .htaccess issue, and yet, maybe not. Maybe I am looking at the problem from the wrong angle, and thus can't find the proper solution.
I am building a web app + hybrid mobile app. I would like to share the exact same code base, without having to tweak anything manually to deploy my app to Android or iOS, otherwise, the process of deploying will be hacky and painful. What I want is to take the web app repository, shove it into Cordova's box (you dirty man ;), and it would deploy it successfully.
Now, one issue is that Cordova requires relative paths to work properly. For example, this is how I include my require.js file :
<script data-main="library/js/dependencies.js" src="library/js/libs/require.js">
</script>
This works fine on the hybrid app. This works fine also on most of the web app's URLs, those with the following scheme :
domain.com/view_name
However, this is what happens when I load the app from a view that receives URI parameters :
domain.com/view_name/6iwO4NyJqy
The relative paths are not resolved properly anymore. I get 404 error due to unproper paths. For instance, this is how is resolved the require.js file above :
http://domain.com/view_name/library/js/libs/require.js
The view_name bit is the wrong part. It should not be there. Without it, the file would be found successfully.
This is my .htaccess file :
RewriteEngine on
RewriteBase /
# REROUTING EVERYTHING TO index.html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d [OR]
RewriteCond %{REQUEST_URI} ^/$
RewriteRule .* /index.html [NC,L,QSA]
Is there a way to set my .htaccess file, so that I don't need to modify the relative paths within the app, and still can have them resolved properly ?
Any suggestion is most welcome.
It is not caused by your rewrite rule, it is due to your use of relative paths.
You can add this just below <head> section of your page's HTML:
<base href="/" />
so that every relative URL is resolved from that base URL and not from the current page's URL.
Related
My application is in a subdirectory of the main web site. I have implemented basename and browserHistory and put the following recommended apache rewrite code into .htaccess in the app folder:
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.html [L]
This recommended apache rewrite works to return browserHistory URLs to the application index.html. For some reason (see below), it does not find the "style.css" and "brundle.js" that are EMBEDDED in the index page HTML. The only thing that I can see that I have different in the example .htaccess file is that I have a RewriteBase value of "/react_librivox_search" because my application is in that subfolder of the site.
RewriteBase /react_librivox_search
I have tested using various different beginning and ending slashes for paths and files in .htaccess, and the problem is not that.
The problem seems to be that the react application is setting a GET value for the files that includes a part of the PATH variable that is supposedly only a part of the react-router definition:
<Route path="/book/:id" component={BookDataDisplay}/>
Note that the additional path segment "/book/" is being appended to the base URL, and when files are not found in THAT directory (which does not really exist), the server returns "index.html" for the missing files, which accounts for the mime-type error for the librivox_search.css file and the "<" error for the bundle.js file.
The stylesheet http://jstest.dd:8083/react_librivox_search/book/librivox_search.css was not loaded because its MIME type, “text/html”, is not “text/css”. librivox_search.css (embedded in index.html)
SyntaxError: expected expression, got '<' bundle.js (embedded in index.html)
The same unexpected addition of "book" to the URL is at work here as well. Neither of the embedded index.html files is in that subdirectory. But I want to maintain that "book" in the path, since it identifies what KIND of data is being passed to the route . . . which distinquishes it from other kinds of data. I just do not want to have it sent to the SERVER (but perhaps that cannot be avoided), since the actual index.html embedded files are not there.
I suppose rewriting "/react_librivox_search/book" as "/react_librivxo_search" might work, but it seems to be a hacky way to go about it. And I don't want to have to put duplicate bundle.js files in multiple directories (that works, but
what a maintenance nightmare THAT would be, and no doubt bad practice).
Or is it recommended to put a separate .htaccess in a REAL "book" subfolder that returns "librivox_search.css" and "bundle.js" (in the base directory) depending on the file request?
I have a web page which works fine on live server. However some links to files (jpg, pdf and others) which are created with cms editor contain relative paths.
When I run that page on my local test server which serves the pages out of a sub folder of localhost the relative paths to the files are wrong since they are missing the subfolder at the beginning. The html page loads fine. It's just some files in it that have wrong path and won't load.
page loads from http://localhost/level1/
files are trying to load from http://localhost/level2/ and I get 404s.
They should be loading from http://localhost/level1/level2/
So I setup a RewriteRule to correct the path but no matter what I have tried I can't get it to work. I have tried various flags including [R,L] but nothing changes the URI in the html.
currently I have:
RewriteRule ^/level2/(.*)$ /level1/level2/$1 [R]
Any suggestions?
Thanks
Sounds like those links are not relative paths but absolute ones (starting with a leading slash (/). That is why the issue occurs at all. Relative paths make much more sense.
This would be the version to be used inside your http servers host configuration:
RewriteEngine on
RewriteRule ^/level2/(.*)$ /level1/level2/$1 [L,QSA]
Here the version for .htaccess style files (note the missing leading slash):
RewriteEngine on
RewriteRule ^level2/(.*)$ /level1/level2/$1 [L,QSA]
You could use a version that can be used in both situations:
RewriteEngine on
RewriteRule ^/?level2/(.*)$ /level1/level2/$1 [L,QSA]
Note however that in general one should always prefer to place such rules inside the http servers host configurations. .htaccess style files are notoriously error prone, hard to debug and they really slow down the server, often for nothing. .htaccess style files only offer a last option for those who are using a really cheap web hosting provider. Or for situations where a web application has to write its own rewrite rules, which obviously is a security nightmare on its own...
I have a web interface that i need to maintain and improve, written in a plain old CGI.pm way. That app is not using templating system neither. It's served by apache, like that:
/var/www/vhost/myapp/cgi-bin/app.cgi
/htdocs/css/styles.css
/htdocs/js/script.js
To add new pages to that app, and make my life easyer, i want to host a Dancer or Dancer2 app next to it, i was thinking about something like that:
/var/www/vhost/myapp/cgi-bin/app.cgi
/cgi-bin/dispatch.cgi (the one from Dancer2)
/htdocs/css/styles.css
/js/script.js
/dancer_public/...
/dancer2/lib/...
/views/...
/environement/...
In the dispatcher, i'm changing the path to reach the Dancer2 bin/app.psgi.
I added the following .htaccess file to the htdocs dir:
# BEGIN dancer application htaccess
RewriteEngine On
RewriteBase /v2
RewriteRule ^/v2$ /cgi-bin/dispatch.cgi [L]
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule v2/(.*) /cgi-bin/dispatch.cgi/$1 [L]
# END dancer application htaccess
By doing that,
accesssing to example.com/cgi-bin/app.cgi show me the old app
as expected
accesssing to example.com/v2 show me the dancer
app home page, default one, without css, which is expected as i moved
the public dir, and some other modification
Now that you have the setup, here is where i have an issue,
the redirection from v2 to the dancer app is working really well, however, in order to keep consistent, i would like to have the uri_for creating url from v2 , but it's using the SCRIPT_NAME as base url, to show the issue, when i'm creating that url: uri_for('/mypage'),
i would like to have that url : example.com/v2/mypage,
but instead i have url example.com/cgi-bin/dispatch.cgi/mypage
SCRIPT_NAME environment variable is containing cgi-bin/dispatch.cgi , i have one terrible hack, that is working, but clearly not the solution, i can have my expected behavior by forcing SCRIPT_NAME to /v2 in the cgi dispatcher, in a BEGIN block.
If someone as a clean solution for that, that would be of a great help!
Thanks
Have the same problem with D1.
$ENV{SCRIPT_NAME} = '';
inside dispatch.fcgi helps me.
This is a little bit tricky trouble.
I was setting up a new development environment, which includes the below:
vagrant 1.6.3
Apache/2.2.15 (Unix)
php 5.4.32
ZendFrameword2
The trouble I am running into is that I can't refresh the change of css file properly.
What I have tried is,
put META tags for no-cache like
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
force a browser to get the latest file by
<link rel="stylesheet" type="text/css" charset="utf-8" href="/path/to/css_file.css?<?php time() ?>" />
But I found out there is no difference with the above.
I found that I make it to refresh a css file with the following process
remove the css file
access from my browser and confirm it doesn't exit by showing error message.
and remake the css file and access it.
I get a refreshed file.
Next, I google about Cashing Algorithm for ZendFramework2, and test loading with ZF2 files that may relate to caching control.
It resulted no ZF2 File is related when just to load css file.
Then I notice that if the css file is quite small, it properly refreshed. so I checked various condigions and I found out that I get this trouble when the file size is over 255B.
the rest of part I can inspect is, .htaccess or apache setting files on a server.
.htaccess file under the public directory of ZF2 is:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR] RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^.*$ - [NC,L]
RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$ RewriteRule ^(.*) - [E=BASE:%1] RewriteRule ^(.*)$ %{ENV:BASE}index.php [NC,L]
RewriteCond %{REQUEST_URI} ^/phpmyadmin/(.*)$ RewriteRule ^.*$ - [L]
Do you guess any causes? any advice?
I haven't solved this question yet, but I specified what is the problem actually.
The matter is,
What apache module is lacking when I can't write over 255byte in a file on document root?
so, I am closing this question for now.
Finally! I got the true problem and have solved it.
Additional Experiments after the first post are
1) I replicated the same situation with .js file, and .index
→ So I confirmed that it was not a trouble about css
2) I replaced simple htdocs directory with the one with ZF2 to simplify the situation and discovered that the phenomenon still happened.
→ ZF2 has nothing to do with this problem.
3) I suspected Apache settings next, so I stoped apache and installed and started nginx. Surprisingly for me, the trouble kept happening.
→ Apache settings / modules are not causing the problem.
4) directory errors on guest OS working on vagrant hit to my mind, and vagrant up again with a different synced folder
→ I got no difference.
5) I was finally sure that vagrant is somehow causing this problem, and found the true cause after a few minutes of search.
The solution for this problem is
to add
EnableSendfile off
for httpd.conf if you use apache, and
sendfile off;
for nginx
Related links are below:
Vagrant/VirtualBox/Apache2 Strange Cache Behaviour
https://coderwall.com/p/ztskha
http://abitwiser.wordpress.com/2011/02/24/virtualbox-hates-sendfile/
I shaped two different RewriteRules for my page:
# Enable URL Rewriting
RewriteEngine on
# exclude followed stuff
RewriteRule ^(js|img|css|favicon\.ico|image\.php|anprobe|content|libs|flash\.php|securimage)/ - [L,QSA,S=2]
# conditions (REQUEST dont point # file|dir|link)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-F
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
# rules
RewriteRule ^(?!index\.php)brillen/(.*(brillen)|360|neu)/(.*)([a-zA-Z0-9]{5}-[a-zA-Z0-9]{5}(?!\.))(.*)$ /index.php/brillen/$1?art_id=$4&$5&%{QUERY_STRING} [NS,QSA,L]
RewriteRule ^(?!index\.php)(.*)$ /index.php/$1 [NS,QSA,L]
... and I'm encountering a strange problem, which lies in every request causing the page internally to load twice, which leads to the problem that db actions and email dispatching are also executed twice.
Does anyone have an idea concerning that?
Thanks in advance!
Note 1: All requested resources are valid and available according to the browser's resource tracking.
Note 2: May the problem originate in retaining and post-processing the PATH_INFO? (/index.php/$1 => /index.php/foo/bar/...)
The rewrite Engine cannot make a single HTTP request run twice. It routes the HTTP request for Apache to either a static file, a proxy function, or a module (like PHP) with alteration in the request. But it cannot clone the request and give it 2 times to apache.
When you have any "run twice" problem chances are that you are hit by the empty image url bug. In fact it's not really a bug it's a feature of HTML (at least before HTML5) and a feature of url-parsing.
If you get somewhere an empty GET url, HTML states that the browser should re-send the same query (the one that gave him the current page) with same parameters. This can make a POST request happen 2 times (if the requested 1st page were a POST). So where are these empty GET url? Most of the time you get either :
<IMG SRC="" ...> (in the HTML)
or:
url() (in the css)
or:
<script type="text/javascript" src=""></script>
<link rel="stylesheet" type="text/css" href=""> (in the HTML headers)
Read also #Jon answer about the favicon query. You should always test the result without browsers behaviours by using wget or telnet 80 queries.
Update: detailled explanations and followups available on this blog with HTML5 additions which should remove this behavior for modern browsers.
I had the same issue (or so I thought). It was caused by the request for favicon.ico, which I hadn't considered in my rewrite rule.
I had the same problem, caused because I did some url rewriting, and the script was being loaded twice, due to the fact that i did not add this:
RewriteRule ^(js|img|css|favicon\.ico)/ - [L,QSA,S=2]
This will stop the script from being loaded twice; it solved my problem.