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

