Vue.js Router:历史模式和AWS S3(默认规则)

mhd8tkvw  于 2023-11-21  发布在  Vue.js
关注(0)|答案(7)|浏览(159)

我有一个Vue.js应用程序,并与Amazon S3和Cloudflare一起运行。
当我打开索引并浏览到/dashboard时,一切正常。但是当我直接在新选项卡中打开dashboard之类的路由或刷新页面时,我从S3返回以下错误:

404 Not Found

Code: NoSuchKey
Message: The specified key does not exist.
Key: unternehmen
RequestId: 6514F8A1F4C29235
HostId: +BVrPLJSGdzSYogzWZ4GMBXkgkdSJWRVJVhcSs4EI/lmMUR422aCtCxpBGU6AMe5VkS1UbEn/Lc=

字符串
只是读到问题是Vue.js历史模式:https://router.vuejs.org/de/essentials/history-mode.html
我想用Amazon S3 Bucket中的路由规则解决这个问题。Apache RewriteRule如何查找S3?

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>


已尝试以下操作,但不起作用:

<RoutingRules>
  <RoutingRule>
    <Condition>
      <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
    </Condition>
    <Redirect>
      <HostName>domain.com</HostName>
      <ReplaceKeyWith>index.html</ReplaceKeyWith>
    </Redirect>
  </RoutingRule>
</RoutingRules>


如果我这样做,我只是得到我的页眉和页脚渲染,但仅此而已。
谢谢你,谢谢

bis0qfac

bis0qfac1#

我知道这个答案来得很晚,但如果其他人正在寻找另一种方法来解决这个问题,在没有找到页面时,没有必要在s3上创建自定义页面重定向用户。


的数据
这将始终重定向到/index.html的情况下,一个文件没有找到,这将使应用程序路由触发。

ghhaqwfi

ghhaqwfi2#

如果您在AWS S3上使用静态托管,并且这是SPA应用程序(React,Vue,Angular等),则应将index.html设置为错误页面:

2guxujil

2guxujil3#

我使用“Static website hosting”在S3上托管了一个用Vue制作的静态PWA,它按预期工作。我做的很简单-我添加了这个:

<RoutingRules>
  <RoutingRule>
    <Condition>
      <HttpErrorCodeReturnedEquals>403</HttpErrorCodeReturnedEquals>
    </Condition>
    <Redirect>
      <ReplaceKeyWith></ReplaceKeyWith>
    </Redirect>
  </RoutingRule>
</RoutingRules>

字符串
到S3存储桶的属性。参见下图:x1c 0d1x
对于我的S3存储桶,每次你试图访问一个不存在的文件时,你都会收到一个403(禁止)而不是404。这就是为什么我把HttpErrorCodeReturnedEquals改为403。我还把ReplaceKeyWith替换为一个空字符串“index.html”,因为它没有触发正确的路由。
希望能帮上忙。
干杯,亚历克斯

vc6uscn9

vc6uscn94#

我认为这个问题有两个组成部分:
1.
如果一个请求是直接(在JavaScript应用程序外部)发送到一个子路径,比如/jobs,那么S3会返回404,因为路径/对象不存在。解决这个问题最简单的方法是从S3内部,在那里你将所有错误页面重定向回index.html。
但是,这在Cloudfront等CDN上不起作用,可能是Cloudflare。
一个很好的技巧是使用S3内部的文件来重定向用户,如下所示:
jobs/ ->/index. html jobs ->/index. html
例如,如果有人向site/发出请求,他们将获得以下html文件:

"redirect":"<html><head><meta http-equiv=\"refresh\" content=\"0; url=http://example.com/site/index.html\" /></head>
<body>Redirecting to <a href=\"http://example.com/site/index.html\">Home</a></body></html>"

字符串
其次...
如果我这样做,我只是得到我的页眉和页脚渲染,但仅此而已。
这是我遇到的一个问题,路由器视图不能正确初始化,即使包含路由器视图的组件已经加载。
我现在所做的是在创建主“应用程序”组件时重定向我的路由器:

created () {
console.log('route', this.$route.path)
this.$router.replace(this.$route.query.redirect || '/')
}


这有额外的好处,从你的路径中删除index.html(这是你的新重定向放在那里的),同时迫使你的路由器视图渲染.
我的#app组件是父组件,有一个导航栏,页脚和呈现所有子页面/组件的路由器视图。

olmpazwi

olmpazwi5#

在历史模式下使用路由而不使用CloudFront的一种方法是创建URI将指向的文件。因此,假设您使用index.html作为入口点,并且只有一个其他页面,您给它给予路径page2.html。
然后,您应该调整您的构建和部署过程,以执行以下操作:
1.将您的源代码构建到生产发行版中(例如,使用npm run build
1.请确保您的路由器链接,你创建一个文件,每个路径是原始文件的副本。在我提到的例子中,它将创建一个副本的'dist/index.html'到'dist/page2.html'
1.将dist文件夹内容复制到S3存储桶
请注意,步骤1和2的顺序很重要。这可以很容易地在发布网站的脚本中完成。我刚刚使用了这种方法,得到了我想要的结果;允许刷新页面并在新选项卡中打开链接。
我看到的缺点是:- 存储文件副本的开销-必须确保如果您添加页面,不要忘记更新构建和部署脚本。

mw3dktmi

mw3dktmi6#

第403章我不喜欢你
只有在我添加了类似的400规则之后,我的VUE应用程序才能在历史模式下运行。
对于使用AWS SAM模板的任何人:

CloudFront:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        ...
        CustomErrorResponses:
          - ErrorCode: 404
            ResponseCode: 200
            ResponsePagePath: /index.html
          - ErrorCode: 403
            ResponseCode: 200
            ResponsePagePath: /index.html
          - ErrorCode: 400
            ResponseCode: 200
            ResponsePagePath: /index.html

字符串

wh6knrhe

wh6knrhe7#

适用于使用AWS CDK部署CloudFront分发的用户。
文件在这里。
使用Python CDK部署错误响应的cloudfront分发示例:

origin_access_id = cloudfront.OriginAccessIdentity(scope=self, id="access_id")
self.website_bucket.grant_read(origin_access_id)

distribution = cloudfront.Distribution(
    scope=self,
    id="distribution",
    default_root_object="index.html",
    default_behavior=cloudfront.BehaviorOptions(
        origin=origins.S3Origin(
            bucket=self.website_bucket,
            origin_access_identity=origin_access_id,
        ),
        viewer_protocol_policy=cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
    ),

### ERROR RESPONSE SETUP
    error_responses=[
        cloudfront.ErrorResponse(
            http_status=403,
            response_http_status=200,
            response_page_path="/index.html",
        ),
        cloudfront.ErrorResponse(
            http_status=404,
            response_http_status=200,
            response_page_path="/index.html",
        ),
    ],
###
)

字符串

相关问题