Browse Source

新增跨域检测方法
修复本地上传后cdnurl获取不正确的BUG

Karson 4 years ago
parent
commit
1c1f457e1d

+ 4 - 2
application/admin/controller/Ajax.php

@@ -56,6 +56,8 @@ class Ajax extends Backend
     public function upload()
     {
         Config::set('default_return_type', 'json');
+        //必须设定cdnurl为空,否则cdnurl函数计算错误
+        Config::set('upload.cdnurl', '');
         $chunkid = $this->request->post("chunkid");
         if ($chunkid) {
             if (!Config::get('upload.chunking')) {
@@ -75,7 +77,7 @@ class Ajax extends Backend
                 } catch (UploadException $e) {
                     $this->error($e->getMessage());
                 }
-                $this->success(__('Uploaded successful'), '', ['url' => $attachment->url]);
+                $this->success(__('Uploaded successful'), '', ['url' => $attachment->url, 'fullurl' => cdnurl($attachment->url, true)]);
             } elseif ($method == 'clean') {
                 //删除冗余的分片文件
                 try {
@@ -108,7 +110,7 @@ class Ajax extends Backend
                 $this->error($e->getMessage());
             }
 
-            $this->success(__('Uploaded successful'), '', ['url' => $attachment->url]);
+            $this->success(__('Uploaded successful'), '', ['url' => $attachment->url, 'fullurl' => cdnurl($attachment->url, true)]);
         }
 
     }

+ 4 - 2
application/api/controller/Common.php

@@ -50,6 +50,8 @@ class Common extends Api
     public function upload()
     {
         Config::set('default_return_type', 'json');
+        //必须设定cdnurl为空,否则cdnurl函数计算错误
+        Config::set('upload.cdnurl', '');
         $chunkid = $this->request->post("chunkid");
         if ($chunkid) {
             if (!Config::get('upload.chunking')) {
@@ -69,7 +71,7 @@ class Common extends Api
                 } catch (UploadException $e) {
                     $this->error($e->getMessage());
                 }
-                $this->success(__('Uploaded successful'), ['url' => $attachment->url]);
+                $this->success(__('Uploaded successful'), ['url' => $attachment->url, 'fullurl' => cdnurl($attachment->url, true)]);
             } elseif ($method == 'clean') {
                 //删除冗余的分片文件
                 try {
@@ -102,7 +104,7 @@ class Common extends Api
                 $this->error($e->getMessage());
             }
 
-            $this->success(__('Uploaded successful'), ['url' => $attachment->url]);
+            $this->success(__('Uploaded successful'), ['url' => $attachment->url, 'fullurl' => cdnurl($attachment->url, true)]);
         }
 
     }

+ 34 - 1
application/common.php

@@ -97,7 +97,7 @@ if (!function_exists('is_really_writable')) {
 
     /**
      * 判断文件或文件夹是否可写
-     * @param    string $file 文件或目录
+     * @param string $file 文件或目录
      * @return    bool
      */
     function is_really_writable($file)
@@ -362,3 +362,36 @@ if (!function_exists('hsv2rgb')) {
         ];
     }
 }
+
+if (!function_exists('cors_request_check')) {
+    /**
+     * 跨域检测
+     */
+    function cors_request_check()
+    {
+        if (isset($_SERVER['HTTP_ORIGIN']) && $_SERVER['HTTP_ORIGIN']) {
+            $info = parse_url($_SERVER['HTTP_ORIGIN']);
+            $domainArr = explode(',', config('fastadmin.cors_request_domain'));
+            $domainArr[] = request()->host();
+            if (in_array("*", $domainArr) || in_array($_SERVER['HTTP_ORIGIN'], $domainArr) || (isset($info['host']) && in_array($info['host'], $domainArr))) {
+                header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
+            } else {
+                header('HTTP/1.1 403 Forbidden');
+                exit;
+            }
+
+            header('Access-Control-Allow-Credentials: true');
+            header('Access-Control-Max-Age: 86400');
+
+            if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
+                if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])) {
+                    header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
+                }
+                if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) {
+                    header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
+                }
+                exit;
+            }
+        }
+    }
+}

+ 10 - 26
application/common/controller/Api.php

@@ -91,24 +91,8 @@ class Api
      */
     protected function _initialize()
     {
-        if (Config::get('url_domain_deploy')) {
-            $domain = Route::rules('domain');
-            if (isset($domain['api'])) {
-                if (isset($_SERVER['HTTP_ORIGIN'])) {
-                    header("Access-Control-Allow-Origin: " . $this->request->server('HTTP_ORIGIN'));
-                    header('Access-Control-Allow-Credentials: true');
-                    header('Access-Control-Max-Age: 86400');
-                }
-                if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
-                    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])) {
-                        header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
-                    }
-                    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) {
-                        header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
-                    }
-                }
-            }
-        }
+        //跨域请求检测
+        cors_request_check();
 
         //移除HTML标签
         $this->request->filter('trim,strip_tags,htmlspecialchars');
@@ -164,7 +148,7 @@ class Api
      */
     protected function loadlang($name)
     {
-        $name =  Loader::parseName($name);
+        $name = Loader::parseName($name);
         Lang::load(APP_PATH . $this->request->module() . '/lang/' . $this->request->langset() . '/' . str_replace('.', '/', $name) . '.php');
     }
 
@@ -230,8 +214,8 @@ class Api
     /**
      * 前置操作
      * @access protected
-     * @param  string $method  前置操作方法名
-     * @param  array  $options 调用参数 ['only'=>[...]] 或者 ['except'=>[...]]
+     * @param string $method  前置操作方法名
+     * @param array  $options 调用参数 ['only'=>[...]] 或者 ['except'=>[...]]
      * @return void
      */
     protected function beforeAction($method, $options = [])
@@ -273,11 +257,11 @@ class Api
     /**
      * 验证数据
      * @access protected
-     * @param  array        $data     数据
-     * @param  string|array $validate 验证器名或者验证规则数组
-     * @param  array        $message  提示信息
-     * @param  bool         $batch    是否批量验证
-     * @param  mixed        $callback 回调方法(闭包)
+     * @param array        $data     数据
+     * @param string|array $validate 验证器名或者验证规则数组
+     * @param array        $message  提示信息
+     * @param bool         $batch    是否批量验证
+     * @param mixed        $callback 回调方法(闭包)
      * @return array|string|true
      * @throws ValidateException
      */

+ 5 - 1
application/common/model/Config.php

@@ -165,9 +165,12 @@ class Config extends Model
     {
         $uploadcfg = config('upload');
 
+        $uploadurl = request()->module() ? $uploadcfg['uploadurl'] : ($uploadcfg['uploadurl'] === 'ajax/upload' ? 'index/' . $uploadcfg['uploadurl'] : $uploadcfg['uploadurl']);
+
+        $uploadurl = url($uploadurl, '', false, true);
         $upload = [
             'cdnurl'    => $uploadcfg['cdnurl'],
-            'uploadurl' => $uploadcfg['uploadurl'],
+            'uploadurl' => $uploadurl,
             'bucket'    => 'local',
             'maxsize'   => $uploadcfg['maxsize'],
             'mimetype'  => $uploadcfg['mimetype'],
@@ -175,6 +178,7 @@ class Config extends Model
             'chunksize' => $uploadcfg['chunksize'],
             'multipart' => [],
             'multiple'  => $uploadcfg['multiple'],
+            'storage'   => 'local'
         ];
         return $upload;
     }

+ 2 - 0
application/config.php

@@ -273,6 +273,8 @@ return [
         'login_background'      => "/assets/img/loginbg.jpg",
         //是否启用多级菜单导航
         'multiplenav'           => false,
+        //允许跨域的域名,多个以,分隔
+        'cors_request_domain'   => 'localhost,127.0.0.1',
         //自动检测更新
         'checkupdate'           => false,
         //版本号

+ 1 - 1
application/index/controller/Ajax.php

@@ -12,7 +12,7 @@ use think\Lang;
 class Ajax extends Frontend
 {
 
-    protected $noNeedLogin = ['lang'];
+    protected $noNeedLogin = ['lang', 'upload'];
     protected $noNeedRight = ['*'];
     protected $layout = '';
 

File diff suppressed because it is too large
+ 1 - 1
public/assets/css/backend.min.css


File diff suppressed because it is too large
+ 1 - 1
public/assets/css/frontend.min.css


+ 3 - 0
public/assets/js/fast.js

@@ -68,6 +68,9 @@ define(['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, undefine
                 options = $.extend({
                     type: "POST",
                     dataType: "json",
+                    xhrFields: {
+                        withCredentials: true
+                    },
                     success: function (ret) {
                         index && Layer.close(index);
                         ret = Fast.events.onAjaxResponse(ret);

+ 5 - 2
public/assets/js/require-backend.min.js

@@ -731,6 +731,9 @@ define('fast',['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, u
                 options = $.extend({
                     type: "POST",
                     dataType: "json",
+                    xhrFields: {
+                        withCredentials: true
+                    },
                     success: function (ret) {
                         index && Layer.close(index);
                         ret = Fast.events.onAjaxResponse(ret);
@@ -10229,8 +10232,8 @@ define('form',['jquery', 'bootstrap', 'upload', 'validator'], function ($, undef
             },
             faselect: function (form) {
                 //绑定fachoose选择附件事件
-                if ($(".fachoose", form).size() > 0) {
-                    $(".fachoose", form).on('click', function () {
+                if ($(".faselect,.fachoose", form).size() > 0) {
+                    $(".faselect,.fachoose", form).on('click', function () {
                         var that = this;
                         var multiple = $(this).data("multiple") ? $(this).data("multiple") : false;
                         var mimetype = $(this).data("mimetype") ? $(this).data("mimetype") : '';

+ 2 - 2
public/assets/js/require-form.js

@@ -241,8 +241,8 @@ define(['jquery', 'bootstrap', 'upload', 'validator'], function ($, undefined, U
             },
             faselect: function (form) {
                 //绑定fachoose选择附件事件
-                if ($(".fachoose", form).size() > 0) {
-                    $(".fachoose", form).on('click', function () {
+                if ($(".faselect,.fachoose", form).size() > 0) {
+                    $(".faselect,.fachoose", form).on('click', function () {
                         var that = this;
                         var multiple = $(this).data("multiple") ? $(this).data("multiple") : false;
                         var mimetype = $(this).data("mimetype") ? $(this).data("mimetype") : '';

+ 3 - 0
public/assets/js/require-frontend.min.js

@@ -724,6 +724,9 @@ define('fast',['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, u
                 options = $.extend({
                     type: "POST",
                     dataType: "json",
+                    xhrFields: {
+                        withCredentials: true
+                    },
                     success: function (ret) {
                         index && Layer.close(index);
                         ret = Fast.events.onAjaxResponse(ret);