【问题标题】:All css/img files route to the site's homepage所有 css/img 文件都路由到网站的主页
【发布时间】:2019-05-15 14:29:05
【问题描述】:

我从远程服务器拉取了一个 Laravel 应用程序并尝试设置本地版本。

我复制了所有文件和数据库,并设法为本地应用程序提供服务。所有路由似乎都可以工作,除了一个大问题 - 从public 文件夹路由到网站主页的所有资产!

例如,我有一张这样的图片:

<img src="{{ asset('img/main-logo.png') }}" />

在生产服务器上,这会显示图像,源 URL https://www.example.com/img/main-logo.png 并且可以正常工作。

在我的本地服务器上,图像源原来是http://localhost:8005/img/main-logo.png,这应该是正确的,但它没有显示图像。当我尝试在浏览器中打开此 URL 时,它没有显示图像,而是打开了网站主页!

我的根文件夹中有 server.php 文件,public 中有index.php,我的public 文件夹中有以下.htaccess(从生产服务器复制):

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>

    # Force compression for mangled headers.
    # https://developer.yahoo.com/blogs/ydn/pushing-beyond-gzipping-25601.html

    <IfModule mod_setenvif.c>
        <IfModule mod_headers.c>
            SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
            RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
        </IfModule>
    </IfModule>

    <IfModule mod_headers.c>
     <filesMatch "\.(jpg|jpeg|png|gif|webp|js|ico)$">
        Header set Cache-Control "max-age=2628000, public"
     </filesMatch>
    </IfModule>

    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    # Map certain file types to the specified encoding type in order to
    # make Apache serve them with the appropriate `Content-Encoding` HTTP
    # response header (this will NOT make Apache compress them!).

    # If the following file types wouldn't be served without the appropriate
    # `Content-Enable` HTTP response header, client applications (e.g.:
    # browsers) wouldn't know that they first need to uncompress the response,
    # and thus, wouldn't be able to understand the content.

    # http://httpd.apache.org/docs/current/mod/mod_mime.html#addencoding

    <IfModule mod_mime.c>
        AddEncoding gzip              svgz
    </IfModule>

    <IfModule mod_filter.c>
        AddOutputFilterByType DEFLATE "application/atom+xml" \
                                      "application/javascript" \
                                      "application/json" \
                                      "application/ld+json" \
                                      "application/manifest+json" \
                                      "application/rdf+xml" \
                                      "application/rss+xml" \
                                      "application/schema+json" \
                                      "application/vnd.geo+json" \
                                      "application/vnd.ms-fontobject" \
                                      "application/x-font-ttf" \
                                      "application/x-web-app-manifest+json" \
                                      "application/xhtml+xml" \
                                      "application/xml" \
                                      "font/opentype" \
                                      "image/svg+xml" \
                                      "image/x-icon" \
                                      "text/cache-manifest" \
                                      "text/css" \
                                      "text/html" \
                                      "text/javascript" \
                                      "text/plain" \
                                      "text/vtt" \
                                      "text/x-component" \
                                      "text/xml"
    </IfModule>

    RewriteEngine On

    RewriteRule ^robots\.txt$ robots.php

    # rewrite non www to www
    RewriteCond %{HTTP_HOST} ^localhost:8005 [NC]
    RewriteRule ^(.*)$ http://localhost:8005/$1 [L,R=301,NC]

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # redir for last / in url
    RewriteCond %{REQUEST_METHOD} =GET
    RewriteRule ^(.*)\/(\?.*)?$ /$1$2 [NC,L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]

</IfModule>

所以它是相同的 .htaccess,相同的路由,但在生产服务器上加载的资产不会在本地加载。有谁知道为什么会这样以及如何解决它?

我尝试将“public/”添加到资产 URL,也尝试了绝对/相对路径,但没有任何效果。

编辑:与此同时,我尝试以各种方式编辑 .htaccess,甚至完全删除它,网站处理公共资产路由的方式没有任何改变。

编辑 #2:http://localhost:8005/img/main-logo.png 加载网站主页时,http://localhost:8005/public/img/main-logo.png 给出 404 错误

编辑 #3:当我加载 http://localhost:8005/img/main-logo.png 时,它会在“路由”下显示:

【问题讨论】:

  • 你试过我的解决方案了吗?
  • 检查您的 env 文件,我认为必须有一个您没有更改的应用程序 url。
  • 你试过php artisan storage:link吗?也许资产是从存储文件夹提供的,而不是资产目录本身。
  • @jovan 请提供 .env 文件
  • 图片的绝对文件系统路径是什么? DocumentRoot 是什么?您的配置中缺少某些内容...如果您的应用程序安装在根目录(文档根目录?)之外的 /public 子目录中,并且 URL 路径中不包含 /public 子目录,那么您需要 将请求重写到/public 子目录的东西 - 您发布的内容中没有任何内容可以做到这一点?

标签: php laravel .htaccess


【解决方案1】:

我遇到了同样的问题,我已经解决了。尝试这个。 我更改了 /vendor/Illuminate/Foundation/helpers.phpasset() 函数如下:

function asset($path, $secure = null)
{
    return app('url')->asset("public/".$path, $secure);
}

希望能成功

【讨论】:

    【解决方案2】:

    我真的不确定为什么它会在服务器上运行而不是在本地运行,除非服务器上的某些设置/工具与您本地的不同......也许它在 CDN 前面?这将阻止请求甚至访问服务器并从服务获取文件...无论如何,这就是我将如何解决这个问题:

    RewriteRule     ^img/(.*) path/to/public/$1 [L]
    # Handle Front Controller...
    # ...
    

    此添加的行会将所有以 img 开头的内容重写到您的公共目录,这样文件将直接被提供。您需要更改规则以适应任何其他静态资产,就像您可能需要为您的 javascript 和 css 文件执行此操作一样?

    也有可能只在目标文件存在时才重写,但就我而言,我更喜欢给出 404 错误而不是让用户访问主页。

    编辑:请注意,此答案使用我的全局 htaccess 知识。我不太了解 Laravel,它可能会处理来自其 PHP 的静态资产......但无论框架如何,我的解决方案都应该可以工作。

    【讨论】:

    • 不幸的是,这不起作用。我还尝试了各种绝对路径,无论是否带有 URL 的“public/”部分,但结果仍然相同。
    【解决方案3】:

    只需如下替换您的主目录 .htaccess 文件并尝试。它将在服务器以及您的本地工作。确保备份原始 htaccess 文件。

    <IfModule mod_rewrite.c>
        <IfModule mod_negotiation.c>
            Options -MultiViews
        </IfModule>
    
        RewriteEngine On
    
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule ^(.*)/$ /$1 [L,R=301]
    
        RewriteCond %{REQUEST_URI} !(\.css|\.js|\.png|\.jpg|\.gif|robots\.txt)$ [NC]
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteRule ^ index.php [L]
    
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_URI} !^/public/
        RewriteRule ^(css|js|images)/(.*)$ public/$1/$2 [L,NC]
    
    </IfModule> 
    

    【讨论】:

    • 这不会改变任何事情,对不起。
    • 您是否将您的 index.php 从 public 复制到 home ?你能告诉我你的本地网络服务器名称吗? xampp/wampp?
    • 不,我没有,我不应该需要。我不希望我的本地设置与生产设置不同。我所有的应用程序都使用主文件夹中的 server.php 和公共文件夹中的 index.php 运行。这是 xampp。
    • 您好 这个问题是虚拟主机问题。我会将我的解决方案作为新命令发布,请遵循。
    • @jovan,检查我的解决方案 [link]stackoverflow.com/questions/53777674/…
    【解决方案4】:

    您的服务器使用 apache 的自定义模块,例如 deflate, gzip,但可能这些模块没有在您的本地计算机上。

    首先,您可以尝试在 .htaccess 文件中使用以下代码作为 laravel 的默认内容。

    <IfModule mod_rewrite.c>
        <IfModule mod_negotiation.c>
            Options -MultiViews -Indexes
        </IfModule>
    
        RewriteEngine On
    
        # Handle Authorization Header
        RewriteCond %{HTTP:Authorization} .
        RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
    
        # Redirect Trailing Slashes If Not A Folder...
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteCond %{REQUEST_URI} (.+)/$
        RewriteRule ^ %1 [L,R=301]
    
        # Handle Front Controller...
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteRule ^ index.php [L]
    </IfModule>
    

    如果上面的代码可以正常工作,你可以尝试安装这些自定义模块。

    【讨论】:

    • 我同时写了。 :) 更改 .htaccces 文件后,您是否尝试在浏览器的隐身窗口上进行测试?有时它会缓存在浏览器上。
    • 我尝试清除缓存甚至不同的浏览器,没有变化。
    【解决方案5】:

    将以下代码添加到 apache 文件夹 C:\xampp\apache\conf\extra\httpd-vhosts.conf 下的虚拟主机文件中。

    <VirtualHost *:8005>
      ServerName my-app.local
      DocumentRoot "C:/XAMPP/htdocs/laravel/public"
      <Directory "C:/XAMPP/htdocs/laravel/public">
        Options +Indexes +Includes +FollowSymLinks +MultiViews
        AllowOverride All
        Require local
      </Directory>
    </VirtualHost>
    

    注意:将 laravel 替换为您的 project folder 名称。

    在此之后从C:\Windows\System32\drivers\etc\hosts 编辑您的主机文件并添加以下行

    127.0.0.1 my-app.local
    

    最后重启你的apache,重启后尝试使用http://my-app.local访问你的应用程序

    注意:不要忘记从 HTACCESS 文件中删除所有更改

    希望能成功

    【讨论】:

      猜你喜欢
      • 2013-08-22
      • 2013-02-09
      • 1970-01-01
      • 2023-04-07
      • 2022-10-23
      • 1970-01-01
      • 2016-04-25
      • 2014-11-15
      • 2018-02-14
      相关资源
      最近更新 更多