使用 Phoenix 提供多个动态图像时出现问题(有些负载,有些不负载)

Problem serving multiple dynamic images with Phoenix (some load, some dont)

技术:Phoenix 1.4.9 问题:在带有 "img" 标签的网页中提供上传的图像,导致一些能够加载而另一些则不能。

已尝试检查图像 link,但图像 link(a.e。/image/1 或 /image/2)每次加载都没有问题。

强制缓存清除也不能证明问题的任何迹象。

如果人们想自己玩代码,这里是 git 存储库:https://github.com/WannesFransen1994/phoenix-dynamic-images

我认为重要的代码: 控制器:

def index(conn, _params) do
    images = Repo.all(Image)
    render(conn, "index.html", images: images)
  end

  def create(conn, %{"upload" => %Plug.Upload{} = up}) do
    {:ok, _u} = up |> ImageContext.create_image()
    redirect(conn, to: Routes.page_path(conn, :index))
  end

  def display(conn, %{"id" => id}) do
    i = Repo.get(Image, id)
    conn |> put_resp_content_type(i.content_type) |> send_file(200, Image.local_path(i))
  end

ImageContext.ex

def create_image(%{filename: _, path: tmp_path, content_type: _} = upload) do
    hash = File.stream!(tmp_path, [], 2048) |> Image.sha256()

    with {:ok, %File.Stat{size: size}} <- File.stat(tmp_path),
         data_merged <- Map.from_struct(upload) |> Map.merge(%{size: size, hash: hash}),
         {:ok, upload_cs} <- %Image{} |> Image.changeset(data_merged) |> Repo.insert(),
         :ok <- tmp_path |> File.cp(Image.local_path(upload_cs)) do
      {:ok, upload_cs}
    else
      {:error, reason} -> Repo.rollback(reason)
    end
  end

图像架构(没有变更集等...)

schema "images" do
    field :filename, :string
    field :content_type, :string
    field :hash, :string
    field :size, :integer
  end
def local_path(%Image{} = upload) do
    [@upload_directory, "#{upload.id}-#{upload.filename}"] |> Path.join()
  end

输出(在图像显示 link 上)有效,但是当我转到生成所有带有 "img" 标签的图像的概览页面时,它们随机加载失败(有时他们都工作,有时 none,有时一半,有时一个工作而其他人不工作)

奇怪的是,当您检查日志时,您会收到以下错误:

** (exit) an exception was raised:
    ** (File.Error) could not read file stats "uploads/images/1-user_upload_3.png": no such file or directory

当文件在那里并且当您重新加载或分开查看图像时它可以工作。

EXTRA:问题的图像。同一个页面,只是重新加载了两次:

解决方案是使用绝对路径。

显然 Phoenix 有时会更改当前工作目录,例如在重新加载代码时,因此相对路径会失败。

归功于 Nobbz (Slack) 和 Jose Valim(Git 期)。