作者 Karson

新增跨域检测方法

修复本地上传后cdnurl获取不正确的BUG
... ... @@ -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)]);
}
}
... ...
... ... @@ -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)]);
}
}
... ...
... ... @@ -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;
}
}
}
}
... ...
... ... @@ -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
*/
... ...
... ... @@ -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;
}
... ...
... ... @@ -273,6 +273,8 @@ return [
'login_background' => "/assets/img/loginbg.jpg",
//是否启用多级菜单导航
'multiplenav' => false,
//允许跨域的域名,多个以,分隔
'cors_request_domain' => 'localhost,127.0.0.1',
//自动检测更新
'checkupdate' => false,
//版本号
... ...
... ... @@ -12,7 +12,7 @@ use think\Lang;
class Ajax extends Frontend
{
protected $noNeedLogin = ['lang'];
protected $noNeedLogin = ['lang', 'upload'];
protected $noNeedRight = ['*'];
protected $layout = '';
... ...
... ... @@ -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);
... ...
... ... @@ -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") : '';
... ...
... ... @@ -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") : '';
... ...
... ... @@ -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);
... ...