跨域请求问题

1. 运行环境

使用phpstudy配置的环境
Nginx1.15.11

1). 当前使用的 Laravel 版本?

8.83

2). 当前使用的 php/php-fpm 版本?

7.43

2. 问题描述?

在配置了一个允许跨域请求的中间件后,可以进行数据库操作的跨域请求,但是无法上传文件,上传文件仍然会被cors阻止,以下是代码

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class Cors
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse)  $next
     * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
     */
    public function handle(Request $request, Closure $next)
    {
        return $next($request)
        ->header('Access-Control-Allow-Origin','*')
        ->header('Access-Control-Allow-Methods','POST, GET, OPTIONS, PUT, DELETE')
        ->header('Access-Control-Allow-Credentials','true')
        ->header('Access-Control-Allow-Headers','*');

    }
}

中间件已经注册了。没有在nginx中进行配置

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
最佳答案

问题解决了,大家听到肯定会无语,前端请求有问题,他不承认,让我反复调试了一下午,然后他偷偷改了,感谢大家的回复,谢谢

1年前 评论
讨论数量: 23

nginx配置一下跨域

1年前 评论
wxlPHP (楼主) 1年前
ShiKi

报错信息在哪里?是不是 nginx 上重复配置了

1年前 评论
nff93

生成环境我都在 nginx 配置跨域

if ($request_method = 'OPTIONS') {
        add_header Access-Control-Allow-Origin $http_origin always;
        add_header Access-Control-Allow-Credentials true always;
        add_header Access-Control-Allow-Methods 'GET, POST, PATCH, DELETE, PUT, OPTIONS' always;
        add_header Access-Control-Allow-Headers 'Version, Authorization, access-token, token, user-token, Accept, apiAuth, User-Agent, Keep-Alive, Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With' always;
        add_header 'Access-Control-Expose-Headers' '*' always;

        return 204;
      }

不过看你的报错信息,貌似不是这个问题

1年前 评论
laravel_peng
  1. 首先判断一下,请求有没有到 Laravel 应用?最简单的办法是,直接在入口文件 public/index.phpdd()
  2. 如果没有到应用,可能是浏览器这一层就卡死了,请求没有被发送出去。
  3. 如果到应用了,并注册了有跨域中间件,还是不起作用是因为,程序没有走到跨域中间件就被卡死了。
  4. 至于走到 Laravel 应用的哪个环节被卡死,需要一步一步 debug 排查。
  5. 但是最直接的方式,是在 public/index.php 写防跨域内容:
    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Headers: Origin, Content-Type, Cookie, Accept');
    header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, OPTIONS');
    header('Access-Control-Allow-Credentials: false');
1年前 评论

你这个跨域实现是不符合标准的,在某些情况下,是会出错的,很多人似乎不能很透彻的理解浏览器完整的一个跨域流程是怎么样的。我大概说一下:
在复杂请求下,浏览器会先发起一个 options请求(跨域预检)来探测服务端是否支持跨域,这个 options请求 他是不会附带请求体参数那些东西的,只有头信息,如果这时候你的控制器接口代码因为客户端请求没有附带参数导致500错误或者抛出形式就是抛出http状态码500,这时候虽然你的响应附加了允许跨域的请求头,但是客户端会误以为你不支持跨域,从而导致请求失败。(还有某些场景,Access-Control-Allow-Origin不能粗暴的指定为*,需明确指定域名,这里我不做详细解释了,自行查阅一下资料)

所以标准做法是,响应 OPTIONS请求 告知客户端支持跨域的时候,不应让代码再流经控制器了,应直接进行终止响应。
以下是我摘取的一段laravel10的跨域组件实现代码,从代码中,也能看到,如果它判断到是OPTIONS请求,是新new了一个response对象,然后直接响应了,不再流过控制器($response = $next($request);)了。

    public function handle($request, Closure $next)
    {
        if (! $this->hasMatchingPath($request)) {
            return $next($request);
        }

        $this->cors->setOptions($this->container['config']->get('cors', []));

        if ($this->cors->isPreflightRequest($request)) {
            $response = $this->cors->handlePreflightRequest($request);

            $this->cors->varyHeader($response, 'Access-Control-Request-Method');

            return $response;
        }

        $response = $next($request);

        if ($request->getMethod() === 'OPTIONS') {
            $this->cors->varyHeader($response, 'Access-Control-Request-Method');
        }

        return $this->cors->addActualRequestHeaders($response, $request);
    }
1年前 评论

直接用 Nginx 配置一下,省事....我之前有个项目用过你这种,也用过扩展包都不行,最后用Nginx配置的。

1年前 评论

file laravel高版本的跨域不是直接在这里配置就可以了?

1年前 评论
忆往昔弹指间 1年前
我爱大可乐 1年前
susa (作者) 1年前
susa (作者) 1年前
忆往昔弹指间 1年前
忆往昔弹指间 1年前
我爱大可乐 1年前
我爱大可乐 1年前
忆往昔弹指间 1年前

建议你用api工具测试一下,有可能是代码已经报错了,然后跨域配置就失效了

1年前 评论

你这个跨域配置的是全局还是分组用的

1年前 评论

问题解决了,大家听到肯定会无语,前端请求有问题,他不承认,让我反复调试了一下午,然后他偷偷改了,感谢大家的回复,谢谢

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!