在 Yii 2.0 的 RESTful APIs 中,跨域资源共享的实现

1、在域名:http://editorweb.wjdev.chinamcloud.cn 中请求接口:http://api.pcs.wjdev.chinamcloud.cn/v1/plan-tasks/274?login_id=2e368664c41b8bf511bcc9c65d86dbc3&login_tid=b26398238620e8cd15b0155cd7aee9b2 ,响应 404 ,所请求的资源上不存在“ Access-Control-Allow-Origin”标头。如图1

图1

OPTIONS http://api.pcs.wjdev.chinamcloud.cn/v1/plan-tasks/274?login_id=2e368664c41b8bf511bcc9c65d86dbc3&login_tid=b26398238620e8cd15b0155cd7aee9b2 404 (Not Found) Access to fetch at 'http://api.pcs.wjdev.chinamcloud.cn/v1/plan-tasks/274?login_id=2e368664c41b8bf511bcc9c65d86dbc3&login_tid=b26398238620e8cd15b0155cd7aee9b2' from origin 'http://editorweb.wjdev.chinamcloud.cn' 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. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

2、决定先在本地环境中自行实现一个前端的 Ajax 请求示例

<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%3E%0A%20%20%20%20%24.post(%22http%3A%2F%2Fapi.pcs-api.localhost%2Fv1%2Fplan-tasks%2F88%3Flogin_id%3D2e368664c41b8bf511bcc9c65d86dbc3%26login_tid%3Db26398238620e8cd15b0155cd7aee9b2%22%2C%20%7B%7D%2C%0A%20%20%20%20%20%20%20%20function(data)%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20console.log(data.code)%3B%0A%20%20%20%20%20%20%20%20%7D%2C%20%22json%22)%3B%0A%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />

3、POST 请求,响应 200,但是无响应数据。如图2

图2

Access to XMLHttpRequest at 'http://api.pcs-api.localhost/v1/plan-tasks/88?login_id=2e368664c41b8bf511bcc9c65d86dbc3&login_tid=b26398238620e8cd15b0155cd7aee9b2' from origin 'http://www.pcs-api.localhost' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
jquery.js:9837 Cross-Origin Read Blocking (CORB) blocked cross-origin response http://api.pcs-api.localhost/v1/plan-tasks/88?login_id=2e368664c41b8bf511bcc9c65d86dbc3&login_tid=b26398238620e8cd15b0155cd7aee9b2 with MIME type application/json. See https://www.chromestatus.com/feature/5629709824032768 for more details.

4、参考跨域资源共享 CORS 机制:https://www.yiiframework.com/doc/guide/2.0/zh-cn/structure-filters#cors ,将 Cross-Origin Resource Sharing 过滤器添加到控制器

    /**
     * {@inheritdoc}
     */    public function behaviors()
    {
        $behaviors = parent::behaviors();

        // remove authentication filter
        $auth = $behaviors['authenticator'];
        unset($behaviors['authenticator']);

        // add CORS filter
        $behaviors['corsFilter'] = [
            'class' => Cors::className(),
        ];

        // re-add authentication filter
        $behaviors['authenticator'] = $auth;
        // avoid authentication on CORS-pre-flight requests (HTTP OPTIONS method)
        $behaviors['authenticator']['except'] = ['options'];

        return $behaviors;
    }

5、再次 POST 请求,响应 200,浏览器中的控制台成功输出响应数据的 code。如图3、图4

图3

 

图4

6、因此,需要编辑器的前端有所调整,调整为与 Ajax 的请求示例一致。Content-Type 的值从:application/json 调整为:application/x-www-form-urlencoded。终于服务端接受到请求数据,且响应 200。响应 200 的请求日志数据。如图5

图5

[
    'url' => '/v1/plan-tasks/274?login_id=2e368664c41b8bf511bcc9c65d86dbc3&login_tid=82c3f78c73c01c92b41a90f6b8b88efd',
    'request_query_params' => [
        'id' => '274',
        'login_id' => '2e368664c41b8bf511bcc9c65d86dbc3',
        'login_tid' => '82c3f78c73c01c92b41a90f6b8b88efd',
    ],
    'request_body_params' => [
        '{"id":274,"queryParam":"eyJ0YXNrSWQiOjI3NCwiY2FsbGJhY2tGbGFnIjoiWSIsImNhbGxiYWNrVXJsIjoiaHR0cDovL2FwaS5wY3Mud2pkZXYuY2hpbmFtY2xvdWQuY24vdjEvcGxhbi10YXNrLXJlc291cmNlcy9jYWxsYmFjaz9sb2dpbl9pZD0yZTM2ODY2NGM0MWI4YmY1MTFiY2M5YzY1ZDg2ZGJjMyZsb2dpbl90aWQ9ODJjM2Y3OGM3M2MwMWM5MmI0MWE5MGY2YjhiODhlZmQiLCJlZGl0b3JfdHlwZSI6IjIiLCJlZGl0b3JfdGl0bGUiOiLmkrDlhpnkvpvnqL8tMjAyMDA1MjgtMiIsImVkaXRvcl9pZCI6Mjc0LCJlZGl0b3JfY2FsbGJhY2tfdXJsIjoiaHR0cDovL2FwaS5wY3Mud2pkZXYuY2hpbmFtY2xvdWQuY24vdjEvcGxhbi10YXNrcy8yNzQ/bG9naW5faWQ9MmUzNjg2NjRjNDFiOGJmNTExYmNjOWM2NWQ4NmRiYzMmbG9naW5fdGlkPTgyYzNmNzhjNzNjMDFjOTJiNDFhOTBmNmI4Yjg4ZWZkIiwiZGF0YSI6eyJzb3VyY2UiOiJjaGluYW1jbG91ZF9zY21zIiwiY3VycmVudF9zdGVwX2NvZGUiOiJ3cml0ZV9mZWVkIiwib2JqZWN0X3R5cGUiOiJmZWVkIiwiYXJ0aWNsZV90eXBlX2lkIjoxfX0' => '"}',
    ],
    'user_id' => '3',
    '$_SERVER' => [
        'HTTP_ACCEPT_LANGUAGE' => 'zh-CN,zh;q=0.9',
        'HTTP_ACCEPT' => 'application/json,text/plain, */*',
        'HTTP_HOST' => 'api.pcs.wjdev.chinamcloud.cn',
        'REMOTE_ADDR' => '10.42.22.22',
        'REQUEST_URI' => '/v1/plan-tasks/274?login_id=2e368664c41b8bf511bcc9c65d86dbc3&login_tid=82c3f78c73c01c92b41a90f6b8b88efd',
        'REQUEST_METHOD' => 'POST',
        'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
    ],
]
永夜