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

Docker化Laravel API与NextJS 14应用时遇CORS跨域问题求助

问题:Docker化Laravel API与NextJS 14应用后出现CORS跨域错误

开发环境用php artisan serve和npm run dev运行一切正常,但用docker-compose up --build -d启动容器后,虽能访问localhost:3000(前端)与localhost:8000(后端),但前端向后端发起请求时出现如下CORS错误:

Access to XMLHttpRequest at 'http://127.0.0.1:8000/api/login' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

我的配置文件

config/cors.php

<?php

return [
    'paths' => ['api/*'],

    'allowed_methods' => ['*'],

    'allowed_origins' => ['*'],

    'allowed_origins_patterns' => [],

    'allowed_headers' => ['*'],

    'exposed_headers' => [],

    'max_age' => 0,

    'supports_credentials' => false,

];

目录结构

/api
    - Dockerfile
    - docker-compose.yml
/webapp
    - Dockerfile

API目录下的Dockerfile

FROM php:8.2-apache

RUN apt-get update && apt-get install -y libpng-dev libjpeg-dev libfreetype6-dev zip unzip git
RUN docker-php-ext-configure gd --with-freetype --with-jpeg
RUN docker-php-ext-install gd pdo_mysql

WORKDIR /var/www/html

COPY . .

ENV APACHE_DOCUMENT_ROOT /var/www/html/public
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}/!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf

EXPOSE 80

webapp目录下的Dockerfile

FROM node:20

WORKDIR /app

COPY package*.json ./
RUN npm install

COPY . .

RUN npm run build

CMD ["npm", "start"]

EXPOSE 3000

API目录下的docker-compose.yml

version: '3.8'
services:
  api:
    build:
      context: .
    volumes:
      - .:/var/www/html
      - uploads:/var/www/html/storage/app/public
    ports:
      - "8000:80"
    depends_on:
      - db

  webapp:
    build:
      context: ../webapp
    ports:
      - "3000:3000"

  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
      MYSQL_DATABASE: db
      MYSQL_USER: ${DB_USERNAME}
      MYSQL_PASSWORD: 
      MYSQL_ALLOW_EMPTY_PASSWORD: 1

volumes:
  db_data:
  uploads:
解决方案

1. 确认Laravel CORS中间件已启用

检查app/Http/Kernel.php的$middlewareGroups数组,确保api分组包含HandleCors中间件:

protected $middlewareGroups = [
    'web' => [
        // 其他中间件
    ],

    'api' => [
        \Illuminate\Http\Middleware\HandleCors::class,
        \Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
];

2. 修正前端API请求地址

Docker容器网络中,前端容器访问127.0.0.1:8000指向自身而非宿主机API。需将前端请求地址改为http://api:80/api/login(利用docker-compose服务名api直接访问容器内API服务,端口为容器内部的80),或通过环境变量配置API_BASE_URL统一管理。

3. 清除缓存并重启容器

修改配置后执行以下命令:

# 停止并重建容器
docker-compose down
docker-compose up --build -d

# 进入API容器清除Laravel缓存
docker-compose exec api php artisan config:clear
docker-compose exec api php artisan cache:clear

4. 启用Apache必要模块

在API的Dockerfile中添加启用headers和rewrite模块的命令,确保OPTIONS预检请求能正常转发到Laravel:

RUN a2enmod headers rewrite

添加后重新构建API容器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 17:33:10