laravel 配合 angular跨域问题

发布于 2022-09-04 10:00:40 字数 3301 浏览 18 评论 0

我从a.com发送一个post请求到b.com,显示状态200,但是 failed to load response data.
a.com 请求如下:

$http.post('http://www.b.com/test/index', {
                    name: 'testname',
                    email: 'testemail@qq.com'
                }).then(function (r) {
                    console.log(r);
                });

b.com返回响应:

// test/index路由指向TestController@index方法,如下:
public function index(Request $request)
    {
        foreach (array_keys($this->fields) as $field) {
            //if(!$request->has($field)) return false;
            $this->orderInfo[$field] = $request->get($field);
        }
        
        return response()->json(['status' => 1, 'msg' => 'success'])
            ->header('Access-Control-Allow-Origin', 'http://www.a.com')
            ->header('Access-Control-Allow-Headers', 'Origin, Content-Type, Cookie, Accept')
            ->header('Access-Control-Allow-Methods', 'GET, POST, PATCH, PUT, OPTIONS');
    }

以上代码在a.com结果如下图:

clipboard.png

clipboard.png

还有测试如下:如果header('Access-Control-Allow-Origin', 'http://www.a.com')改成通配符*,返回500,

clipboard.png
在请求中加上withCredentials: true,,同500。

是不是我哪里设置有错?怎么样才能取得response的数据呢?

改成中间件版,如下:

// a.com 发起请求
$http.post('http://www.b.com/test/index', {
                    name: 'testname',
                    email: 'testemail@qq.com'
                }).then(function (r) {
                    console.log(r);
                });

b.com里的代码

//路由
Route::post('test/index', ['middleware' => 'enblecross', 'uses' => 'TestController@index']);

//中间件 EnableCrossRequestMiddleware.php
<?php

namespace App\Http\Middleware;

use Closure;

class EnableCrossRequestMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $response = $next($request);
        $response->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');
        //$response->header('Access-Control-Allow-Credentials', 'true');
        return $response;
    }
}
// 注册
protected $routeMiddleware = [
        //....
        'enblecross' => \App\Http\Middleware\EnableCrossRequestMiddleware::class,
    ];
//TestController@index
public function index(Request $request)
    {
        return ['status' => 1, 'msg' => 'success'];
    }

结果还是一样,偶尔500,偶尔200,报错Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

夏末 2022-09-11 10:00:40

使用curl方式发生错误,初步猜测是因为请求端和响应端都是laravel,APP_KEY问题?不懂。
将APP_KEY设置成相同,去掉VerifyCsrfToken中间件,顺利返回结果。
我使用的laravel5.1版的最新版,也可以在app/Http/Middleware/VerifyCsrfToken.php的$except数组中加上要跳过Csrf验证的路由。

此时,angular $http 使用jsonp、get都没有问题。jquery的ajax方法也都可以。
angular post需要加上头部信息'Content-Type': 'application/x-www-form-urlencoded',顺利得到结果。

$http({
    method: 'post',
    url: 'http://www.b.com/test/index',
    data: {
        //withCredentials: true,
        customers: 'testname',
        email: 'testemail@qq.com'
    },
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    }
}).success(function (r) {
    console.log(r);
});

以下使用方式被转成OPTIONS,发生问题中的origin错误。

$http.post('http://www.b.com/test/index', data, {'Content-Type': 'application/x-www-form-urlencoded'}).success(function (r) {
    console.log(r);
});
作妖 2022-09-11 10:00:40

新建一个中间件,在中间件中设置http header, 路由里面把所有需要跨域的请求放到同一个中间件分组里面。

    public function handle($request, Closure $next)
    {
        $response = $next($request);
        $response->header('Access-Control-Allow-Origin', 'http://www.a.com')
            ->header('Access-Control-Allow-Headers', 'Origin, Content-Type, Cookie, Accept')
            ->header('Access-Control-Allow-Methods', 'GET, POST, PATCH, PUT, OPTIONS');
        return $response;
    }
只等公子 2022-09-11 10:00:40

是这样的,首先是发了一个OPTIONS的预请求,来询问服务器是否接受这次的跨域请求。
接下来才会发正式请求,来接收数据。你找一下看看应该有个POST的响应。你看到的这个是OPTIONS的响应,自然是没有实体数据的。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文