You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Elixir中使用plug_cowboy时如何配置允许CORS跨域请求?

Plug Cowboy 配置CORS跨域权限教程

步骤1:添加CORS处理依赖

在项目的mix.exs文件的依赖列表中添加Corsica,这是Elixir生态中通用的CORS处理库:

defp deps do
  [
    # 项目原有其他依赖
    {:corsica, "~> 2.0"}
  ]
end

添加完成后执行mix deps.get安装依赖。

步骤2:修改Endpoint配置CORS规则

CORS处理插件必须放在所有业务处理插件之前,避免浏览器的预检请求被其他逻辑拦截。修改后的Api.Endpoint完整代码如下:

defmodule Api.Endpoint do
  @moduledoc """
  A plug that parses requests as JSON,
  dispatches responses and
  makes necessary changes elsewhere.
  """

  use Plug.Router

  plug Plug.Logger
  # 新增CORS配置,放于所有业务处理逻辑最前方
  plug Corsica,
    origins: ["http://localhost:3000"],
    allow_headers: ["content-type"],
    allow_methods: ["GET", "POST", "OPTIONS"],
    max_age: 86400

  plug :match
  # Using Poison for JSON decoding
  plug(Plug.Parsers, parsers: [:json], json_decoder: Poison)
  plug :dispatch

  # 新增预检OPTIONS请求专用处理路由
  options _ do
    send_resp(conn, 204, "")
  end

  get "/ping" do
    send_resp(conn, 200, Poison.encode!(%{response: "pong!"}))
  end

  post "/events" do
    {status, body} = 
      case conn.body_params do
        %{"events" => events} -> {200, process_events(events)}
        _ -> {422, missing_events()}
      end

    send_resp(conn, status, body)
  end

  defp process_events(events) when is_list(events) do
    Poison.encode!(%{response: "Received Events!"})
  end

  defp process_events(_) do
    Poison.encode!(%{response: "Please Send Some Events!"})
  end

  defp missing_events do
    Poison.encode!(%{error: "Expected Payload: { 'events': [...] }"})
  end

  match _ do
    send_resp(conn, 404, "oops... Nothing here :(")
  end
end

配置规则说明

  • origins:指定允许跨域访问的来源,这里仅放行你的React应用地址http://localhost:3000,生产环境可以替换为实际前端域名;如果需要允许所有来源可设置为"*",不推荐在生产环境使用。
  • allow_headers:指定允许的请求头,这里配置了JSON请求必需的content-type,如果有自定义请求头可自行添加。
  • allow_methods:指定允许的请求方法,覆盖了当前用到的GET、POST,以及浏览器跨域必需的OPTIONS预检方法。
  • 新增的options _路由专门处理所有预检请求,返回204状态码即可。

无第三方依赖的手动实现方案

如果你不想引入额外依赖,也可以手动编写简易CORS处理Plug:

defmodule CorsPlug do
  import Plug.Conn

  def init(opts), do: opts

  def call(conn, _opts) do
    conn
    |> put_resp_header("access-control-allow-origin", "http://localhost:3000")
    |> put_resp_header("access-control-allow-methods", "GET, POST, OPTIONS")
    |> put_resp_header("access-control-allow-headers", "content-type")
  end
end

将这个Plug添加到Api.Endpoint的最前方即可,同样需要保留OPTIONS路由的处理逻辑。


内容的提问来源于stack exchange,提问作者Ewan H

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 19:57:03