我使用S3托管一个javascript应用程序,将使用HTML5 pushStates。问题是,如果用户书签了任何url,它将不会解析为任何东西。我需要的是能够接受所有url请求,并在我的S3桶中提供根index.html,而不仅仅是进行完全重定向。然后我的javascript应用程序可以解析URL并提供适当的页面。
有没有办法告诉S3为所有URL请求服务index.html,而不是做重定向?这类似于通过提供一个index.html来设置apache来处理所有传入的请求,如本例中的https://stackoverflow.com/a/10647521/1762614。我真的希望避免仅仅为了处理这些路由而运行web服务器。从S3执行所有操作非常有吸引力。
这是切题的,但这里有一个提示,对于那些使用Rackt的React Router库和(HTML5)浏览器历史,想要在S3上托管的人。
假设一个用户在s3托管的静态网站上访问/foo/bear。根据David之前的建议,重定向规则将把它们发送到/#/foo/bear。如果您的应用程序是使用浏览器历史记录构建的,那么这样做不会有太大的好处。然而,你的应用程序在这一点上加载,它现在可以操纵历史。
在我们的项目中包括Rackt历史(参见React Router项目中的使用自定义历史),你可以添加一个侦听器,它可以感知哈希历史路径,并根据需要替换路径,如下例所示:
import ReactDOM from 'react-dom';
/* Application-specific details. */
const route = {};
import { Router, useRouterHistory } from 'react-router';
import { createHistory } from 'history';
const history = useRouterHistory(createHistory)();
history.listen(function (location) {
const path = (/#(\/.*)$/.exec(location.hash) || [])[1];
if (path) history.replace(path);
});
ReactDOM.render(
<Router history={history} routes={route}/>,
document.body.appendChild(document.createElement('div'))
);
回顾一下:
David的S3重定向规则将/foo/bear定向到/#/foo/bear。
您的应用程序将加载。
历史侦听器将检测#/foo/bear历史符号。
用正确的路径替换历史记录。
链接标签将按预期工作,所有其他浏览器历史功能也是如此。我所注意到的唯一缺点是在初始请求时发生的间隙重定向。
这是受到AngularJS的一个解决方案的启发,我怀疑它可以很容易地适应任何应用程序。
这是切题的,但这里有一个提示,对于那些使用Rackt的React Router库和(HTML5)浏览器历史,想要在S3上托管的人。
假设一个用户在s3托管的静态网站上访问/foo/bear。根据David之前的建议,重定向规则将把它们发送到/#/foo/bear。如果您的应用程序是使用浏览器历史记录构建的,那么这样做不会有太大的好处。然而,你的应用程序在这一点上加载,它现在可以操纵历史。
在我们的项目中包括Rackt历史(参见React Router项目中的使用自定义历史),你可以添加一个侦听器,它可以感知哈希历史路径,并根据需要替换路径,如下例所示:
import ReactDOM from 'react-dom';
/* Application-specific details. */
const route = {};
import { Router, useRouterHistory } from 'react-router';
import { createHistory } from 'history';
const history = useRouterHistory(createHistory)();
history.listen(function (location) {
const path = (/#(\/.*)$/.exec(location.hash) || [])[1];
if (path) history.replace(path);
});
ReactDOM.render(
<Router history={history} routes={route}/>,
document.body.appendChild(document.createElement('div'))
);
回顾一下:
David的S3重定向规则将/foo/bear定向到/#/foo/bear。
您的应用程序将加载。
历史侦听器将检测#/foo/bear历史符号。
用正确的路径替换历史记录。
链接标签将按预期工作,所有其他浏览器历史功能也是如此。我所注意到的唯一缺点是在初始请求时发生的间隙重定向。
这是受到AngularJS的一个解决方案的启发,我怀疑它可以很容易地适应任何应用程序。
既然问题仍然存在,我想我提出另一个解决方案。
我的情况是,我想在合并之前自动将所有拉请求部署到s3进行测试,使它们可以在[mydomain]/pull-requests/[pr number]/上访问
(例如www.example.com/pull-requests/822/)
据我所知,没有s3规则的场景允许在一个桶中使用html5路由有多个项目,所以上面大多数投票建议适用于根文件夹中的项目,不适用于自己子文件夹中的多个项目。
所以我把我的域指向我的服务器,在那里遵循nginx配置做的工作
location /pull-requests/ {
try_files $uri @get_files;
}
location @get_files {
rewrite ^\/pull-requests\/(.*) /$1 break;
proxy_pass http://<your-amazon-bucket-url>;
proxy_intercept_errors on;
recursive_error_pages on;
error_page 404 = @get_routes;
}
location @get_routes {
rewrite ^\/(\w+)\/(.+) /$1/ break;
proxy_pass http://<your-amazon-bucket-url>;
proxy_intercept_errors on;
recursive_error_pages on;
error_page 404 = @not_found;
}
location @not_found {
return 404;
}
它尝试获取文件,如果没有找到,则假设它是html5路由并尝试。如果你在angular的404页面中没有找到路由,你将永远不会到达@not_found,而会返回angular 404页面而不是not found files,这可以通过在@get_routes中添加If规则来修复。
我不得不说我在nginx配置和使用regex方面感到不太舒服,我得到了这个工作,经过了一些试验和错误,所以虽然这是有效的,但我相信有改进的空间,请分享你的想法。
注意:如果在s3配置中有重定向规则,请删除它们。
顺便说一下,在Safari中工作