yii验证系统学习记录,基于yiicms(一)写的太长了,再写一篇(二)

项目地址:https://gitee.com/templi/yiicms 感谢七觞酒大神的付出,和免费分享。当然也感谢yii2的开发团队们。

项目已经安全完毕,不知道后台密码,这种背景下,后台无法进去。绕不开的话题就是:

1.后台密码账号如何产生。类似下图:

加密过的字符串自然不能用于登陆。

我尝试通过前台注册一个账户,然后登陆,因为权限不够,尽管等登陆到后台首页,同样无权访问其他任何页面。配置了下modules,

意图通过给予权限系统权限,然后更改刚加入的用户“zhuangli”以管理员角色以及权限分配等。不成功。

我们先来梳理第一个问题,yii2的密码到底是如何产生的?

我们从登陆这里开始,看它一步步都做了什么操作。

只要用户访问,必须经过yii2入口文件index.php,也就是在这个时候新创建了一个application实例,使用了配置文件中的各种配置项以及系统默认给定的几个包括响应组件,请求组件,错误组件等核心组件的实例,附着在该应用上,方便随时供访问。其中这里配置了一个user,当然不配置使用系统默认也是可以的。

'user' => ['identityClass' => 'common\models\User','enableAutoLogin' => true,'identityCookie' => ['name' => '_identity-backend', 'httpOnly' => true],],

这个组件规定了权限类,是否自动登陆以及权限验证cookie

 1 User is the class for the `user` application component that manages the user authentication status.
 2  *
 3  * You may use [[isGuest]] to determine whether the current user is a guest or not.
 4  * If the user is a guest, the [[identity]] property would return `null`. Otherwise, it would
 5  * be an instance of [[IdentityInterface]].
 6  *
 7  * You may call various methods to change the user authentication status:
 8  *
 9  * - [[login()]]: sets the specified identity and remembers the authentication status in session and cookie;
10  * - [[logout()]]: marks the user as a guest and clears the relevant information from session and cookie;
11  * - [[setIdentity()]]: changes the user identity without touching session or cookie
12  *   (this is best used in stateless RESTful API implementation).
13  *
14  * Note that User only maintains the user authentication status. It does NOT handle how to authenticate
15  * a user. The logic of how to authenticate a user should be done in the class implementing [[IdentityInterface]].
16  * You are also required to set [[identityClass]] with the name of this class.
17  *
18  * User is configured as an application component in [[\yii\web\Application]] by default.
19  * You can access that instance via `Yii::$app->user`.
20  *
21  * You can modify its configuration by adding an array to your application config under `components`
22  * as it is shown in the following example:
23  *
24  * ```php
25  * 'user' => [
26  *     'identityClass' => 'app\models\User', // User must implement the IdentityInterface
27  *     'enableAutoLogin' => true,
28  *     // 'loginUrl' => ['user/login'],
29  *     // ...
30  * ]
31  * ```
32  *
33  * @property string|int $id The unique identifier for the user. If `null`, it means the user is a guest. This
34  * property is read-only.
35  * @property IdentityInterface|null $identity The identity object associated with the currently logged-in
36  * user. `null` is returned if the user is not logged in (not authenticated).
37  * @property bool $isGuest Whether the current user is a guest. This property is read-only.
38  * @property string $returnUrl The URL that the user should be redirected to after login. Note that the type
39  * of this property differs in getter and setter. See [[getReturnUrl()]] and [[setReturnUrl()]] for details.
40  *

翻译一下这段对user这个组件的说明:

这是一个user应用组件的类,管理用户的认证状态。可以使用isGuest(实际是getIsGuest)来辨别当前用户是否用游客。如果为游客,identity属性返回null,否则就是IdentityInterface接口的实例。有很多方法可以改变认证状态。

login,设置特定的身份,并将认证状态存在session或cookie中。

loginout,标示为游客,并将有关的信息从session或cookie中清除。

setIndentiy,只改变用户身份,不涉及session和cookie。这最好用于无状态的REST API实现。

 User 仅仅用于维护用户认证状态,它并不负责如何去认证一个用户。如何去认证一个用户的逻辑应在继承至IdentityInterface类中去完成,User这个类也被要求设置为identityClass属性的值。正如这里做的:

它是被默认配置为yii\web\application的一个应用组件,正如我上面所说。可以直接通过Yii::$app->user访问到该组件。当然可以改变配置,通过在配置文件中的components底下加入数组,类似:

'user' => [
'identityClass' => 'app\models\User', // User must implement the IdentityInterface
'enableAutoLogin' => true,
'loginUrl' => ['user/login'],
// ...
]
$id唯一身份标示,为null,代表是游客,只读。$identity关联到当前登入用户的认证对象,null代表未登入(未认证)。$isGuest,当前用户是否游客,只读。$returnUrl,登陆后重定向的url。

继续看登陆的过程。
 1 /**2      * Login action.3      *4      * @return string5      */6     public function actionLogin()7     {8         $this->layout = false;9         var_dump(Yii::$app->user);
10 
11         if (!Yii::$app->user->isGuest) {
12             return $this->goHome();
13         }
14 
15         $model = new LoginForm();
16         if ($model->load(Yii::$app->request->post()) && $model->login()) {
17             return $this->goBack();
18         } else {
19             return $this->render('login', [
20                 'model' => $model,
21             ]);
22         }
23     }
 

首先是判断用户是否游客,不是,重定向到主页去,新建一个loginForm模型实例,这是个登陆表单的虚拟数据模型,将username和password加载到这个model中,验证执行登陆login操作。

 1 /**
 2      * Logs in a user using the provided username and password.
 3      *
 4      * @return bool whether the user is logged in successfully
 5      */
 6     public function login()
 7     {
 8         if ($this->validate()) {
 9             return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600 * 24 * 30 : 0);
10         } else {
11             return false;
12         }
13     }

开步就是验证,这个validate方法是该类的父类model上的方法。

validate点进去是以下这样一个方法: 1 /** 2 * Performs the data validation.

 3      *
 4      * This method executes the validation rules applicable to the current [[scenario]].
 5      * The following criteria are used to determine whether a rule is currently applicable:
 6      *
 7      * - the rule must be associated with the attributes relevant to the current scenario;
 8      * - the rules must be effective for the current scenario.
 9      *
10      * This method will call [[beforeValidate()]] and [[afterValidate()]] before and
11      * after the actual validation, respectively. If [[beforeValidate()]] returns false,
12      * the validation will be cancelled and [[afterValidate()]] will not be called.
13      *
14      * Errors found during the validation can be retrieved via [[getErrors()]],
15      * [[getFirstErrors()]] and [[getFirstError()]].
16      *
17      * @param array $attributeNames list of attribute names that should be validated.
18      * If this parameter is empty, it means any attribute listed in the applicable
19      * validation rules should be validated.
20      * @param bool $clearErrors whether to call [[clearErrors()]] before performing validation
21      * @return bool whether the validation is successful without any error.
22      * @throws InvalidParamException if the current scenario is unknown.
23      */
24     public function validate($attributeNames = null, $clearErrors = true)
25     {
      //清除错误
26 if ($clearErrors) { 27 $this->clearErrors(); 28 } 29
       //前置验证 30 if (!$this->beforeValidate()) { 31 return false; 32 } 33
       //取回场景列表,该方法返回一个场景列表和活跃属性,活跃属性是指当前场景中需要验证的。格式:
       ```php
       * [
       * 'scenario1' => ['attribute11', 'attribute12', ...],
       * 'scenario2' => ['attribute21', 'attribute22', ...],
       * ...
       * ]
       默认情况下,活跃属性被认为安全,可以批量指定。如果不在批量指定之列,则认为不安全,这样请加一个!作为前缀。这个方法的默认实现会返回所有在rules中能找到的场景声明,一个特别的场景
       是SCENARIO_DEFAULT,包括rules中的所有场景。每个场景将都通过运用到场景的验证规则关联到被验证的属性。
34         $scenarios = $this->scenarios();
35         $scenario = $this->getScenario();
36         if (!isset($scenarios[$scenario])) {
37             throw new InvalidParamException("Unknown scenario: $scenario");
38         }
39 
40         if ($attributeNames === null) {
41             $attributeNames = $this->activeAttributes();
42         }
43 
44         foreach ($this->getActiveValidators() as $validator) {
45             $validator->validateAttributes($this, $attributeNames);
46         }
47         $this->afterValidate();
48 
49         return !$this->hasErrors();
50     }

注释翻译:这是一个执行数据验证的方法,这个方法将验证规则应用到当前场景,下面的标准用以决定规则当前是否可用。

规则必须将属性关联到当前场景。规则必须对当前场景有效。

这个方法前后都要调用beforeValidate和afterValidate。中间产生的错误可由getErrors,[[getFirstErrors()]] and [[getFirstError()]]取得。$attributeNames,用以验证的属性列表,如果参数为空,那意味着可应用的规则中的属性都要被验证。也即是这

1 public function getValidators()
2     {
3         if ($this->_validators === null) {
4             $this->_validators = $this->createValidators();
5         }
6         return $this->_validators;
7     }

注释释义:

个参数指定哪些是需要被验证的,不指定就验证所有。

场景的使用方法参考:Yii2 - 场景scenarios用法

捋一下,场景中如果没有在后代model中重写scenarios,那么在所有场景(action)都会执行所有rules指定字段的所有验证(同一字段存在多种验证,同一验证也可能应用到多个字段)。那么场景指定各个场景要验证的字段后,rules中就要用on关键字将指定场景关联到该条rules,这样场景跟验证规则跟字段就一一对应起来了,如果没有on指定场景,那就是应用到所有场景。在controller中应用某场景还需要使用$model->setScenario('update')或者$model->scenario = 'update'来应用。

$this->scenarios();中有一个方法$this->getValidators(),获取验证器。

返回rules中声明的验证器,不同于getActiveValidators的是,这个只返回应用到当前场景的验证器。因为它的返回结果是一个ArrayObject,因此可以手动插入或移除,在model behaviors中很有用。

接下来:

 1 /**
 2      * Creates validator objects based on the validation rules specified in [[rules()]].
 3      * Unlike [[getValidators()]], each time this method is called, a new list of validators will be returned.
 4      * @return ArrayObject validators
 5      * @throws InvalidConfigException if any validation rule configuration is invalid
 6      */
 7     public function createValidators()
 8     {
 9         $validators = new ArrayObject;
10         foreach ($this->rules() as $rule) {
11             if ($rule instanceof Validator) {
12                 $validators->append($rule);
13             } elseif (is_array($rule) && isset($rule[0], $rule[1])) { // attributes, validator type
14                 $validator = Validator::createValidator($rule[1], $this, (array) $rule[0], array_slice($rule, 2));
15                 $validators->append($validator);
16             } else {
17                 throw new InvalidConfigException('Invalid validation rule: a rule must specify both attribute names and validator type.');
18             }
19         }
20         return $validators;
21     }

通过rules中指定的验证规则创建相应验证器。再看看Validator::createValidator方法。

 1  /**
 2      * Creates a validator object.
 3      * @param string|\Closure $type the validator type. This can be either:
 4      *  * a built-in validator name listed in [[builtInValidators]];
 5      *  * a method name of the model class;
 6      *  * an anonymous function;
 7      *  * a validator class name.
 8      * @param \yii\base\Model $model the data model to be validated.
 9      * @param array|string $attributes list of attributes to be validated. This can be either an array of
10      * the attribute names or a string of comma-separated attribute names.
11      * @param array $params initial values to be applied to the validator properties.
12      * @return Validator the validator
13      */
14     public static function createValidator($type, $model, $attributes, $params = [])
15     {
16         $params['attributes'] = $attributes;
17 
18         if ($type instanceof \Closure || $model->hasMethod($type)) {
19             // method-based validator
20             $params['class'] = __NAMESPACE__ . '\InlineValidator';
21             $params['method'] = $type;
22         } else {
23             if (isset(static::$builtInValidators[$type])) {
24                 $type = static::$builtInValidators[$type];
25             }
26             if (is_array($type)) {
27                 $params = array_merge($type, $params);
28             } else {
29                 $params['class'] = $type;
30             }
31         }
32 
33         return Yii::createObject($params);
34     }

$attribute即被验证的字段。$type指验证类,比如required,unique等,可以是闭包,可以是model上自定义的方法,将创建一个内联验证器,也可以是内置的若干验证器,或者是个带有指定class的数组,根据那个class以及其中的验证方法来验证,很灵活很强大。最后一种就是直接就是指定的type本身就是一个类。这是内联验证器的默认方式。

 1  public static $builtInValidators = [
 2         'boolean' => 'yii\validators\BooleanValidator',
 3         'captcha' => 'yii\captcha\CaptchaValidator',
 4         'compare' => 'yii\validators\CompareValidator',
 5         'date' => 'yii\validators\DateValidator',
 6         'datetime' => [
 7             'class' => 'yii\validators\DateValidator',
 8             'type' => DateValidator::TYPE_DATETIME,
 9         ],
10         'time' => [
11             'class' => 'yii\validators\DateValidator',
12             'type' => DateValidator::TYPE_TIME,
13         ],
14         'default' => 'yii\validators\DefaultValueValidator',
15         'double' => 'yii\validators\NumberValidator',
16         'each' => 'yii\validators\EachValidator',
17         'email' => 'yii\validators\EmailValidator',
18         'exist' => 'yii\validators\ExistValidator',
19         'file' => 'yii\validators\FileValidator',
20         'filter' => 'yii\validators\FilterValidator',
21         'image' => 'yii\validators\ImageValidator',
22         'in' => 'yii\validators\RangeValidator',
23         'integer' => [
24             'class' => 'yii\validators\NumberValidator',
25             'integerOnly' => true,
26         ],
27         'match' => 'yii\validators\RegularExpressionValidator',
28         'number' => 'yii\validators\NumberValidator',
29         'required' => 'yii\validators\RequiredValidator',
30         'safe' => 'yii\validators\SafeValidator',
31         'string' => 'yii\validators\StringValidator',
32         'trim' => [
33             'class' => 'yii\validators\FilterValidator',
34             'filter' => 'trim',
35             'skipOnArray' => true,
36         ],
37         'unique' => 'yii\validators\UniqueValidator',
38         'url' => 'yii\validators\UrlValidator',
39         'ip' => 'yii\validators\IpValidator',
40     ];

内联的有以上这么多方法。

 1 /**
 2      * Returns the attribute names that are subject to validation in the current scenario.
 3      * @return string[] safe attribute names
 4      */
 5     public function activeAttributes()
 6     {
 7         $scenario = $this->getScenario();
 8         $scenarios = $this->scenarios();
 9         if (!isset($scenarios[$scenario])) {
10             return [];
11         }
12         $attributes = $scenarios[$scenario];
13         foreach ($attributes as $i => $attribute) {
14             if ($attribute[0] === '!') {
15                 $attributes[$i] = substr($attribute, 1);
16             }
17         }
18 
19         return $attributes;
20     }

返回从属于当前场景的安全属性名列表。

返回应用到当前场景的验证器。$attribute是指需要返回验证器的属性名。如果为null,所有model中的属性将返回。

1 foreach ($this->getActiveValidators() as $validator) {
2   $validator->validateAttributes($this, $attributeNames);
3 }

这个循环对当前场景活跃属性进行验证,验证代码如下:

 1 /**
 2      * Validates the specified object.
 3      * @param \yii\base\Model $model the data model being validated
 4      * @param array|null $attributes the list of attributes to be validated.
 5      * Note that if an attribute is not associated with the validator - it will be
 6      * ignored. If this parameter is null, every attribute listed in [[attributes]] will be validated.
 7      */
 8     public function validateAttributes($model, $attributes = null)
 9     {
10         if (is_array($attributes)) {
11             $newAttributes = [];
12             foreach ($attributes as $attribute) {
13                 if (in_array($attribute, $this->getAttributeNames(), true)) {
14                     $newAttributes[] = $attribute;
15                 }
16             }
17             $attributes = $newAttributes;
18         } else {
19             $attributes = $this->getAttributeNames();
20         }
21 
22         foreach ($attributes as $attribute) {
23             $skip = $this->skipOnError && $model->hasErrors($attribute)
24                 || $this->skipOnEmpty && $this->isEmpty($model->$attribute);
25             if (!$skip) {
26                 if ($this->when === null || call_user_func($this->when, $model, $attribute)) {
27                     $this->validateAttribute($model, $attribute);
28                 }
29             }
30         }
31     }

验证指定的对象,第一个参数$model,要验证的model,第二个参数要被验证的属性列表。注意如果属性没有没有关联到验证器会忽略,如果这个参数为空,attributes中的属性都会被验证。

对scenarios方法的详解:

 1 /**
 2      * Returns a list of scenarios and the corresponding active attributes.
 3      * An active attribute is one that is subject to validation in the current scenario.
 4      * The returned array should be in the following format:
 5      *
 6      * ```php
 7      * [
 8      *     'scenario1' => ['attribute11', 'attribute12', ...],
 9      *     'scenario2' => ['attribute21', 'attribute22', ...],
10      *     ...
11      * ]
12      * ```
13      *
14      * By default, an active attribute is considered safe and can be massively assigned.
15      * If an attribute should NOT be massively assigned (thus considered unsafe),
16      * please prefix the attribute with an exclamation character (e.g. `'!rank'`).
17      *
18      * The default implementation of this method will return all scenarios found in the [[rules()]]
19      * declaration. A special scenario named [[SCENARIO_DEFAULT]] will contain all attributes
20      * found in the [[rules()]]. Each scenario will be associated with the attributes that
21      * are being validated by the validation rules that apply to the scenario.
22      *
23      * @return array a list of scenarios and the corresponding active attributes.
24      */
25     public function scenarios()
26     {
27         $scenarios = [self::SCENARIO_DEFAULT => []];
28         //先做一遍清空,循环类数组对象
29         foreach ($this->getValidators() as $validator) {
30             //rules中指定的on场景清空
31             foreach ($validator->on as $scenario) {
32                 $scenarios[$scenario] = [];
33             }
34             //rules中指定的except场景清空
35             foreach ($validator->except as $scenario) {
36                 $scenarios[$scenario] = [];
37             }
38         }
39 
40         //场景变量中的第一个为self::SCENARIO_DEFAULT,后面依次为上面循环的on和except中的场景
41         //这些场景应该指活跃场景,这些场景是需要验证的,其他不必。
42         $names = array_keys($scenarios);
43 
44         //此处对验证器循环,检查未绑定有和排除了验证的场景,全部置真。
45         //而未绑定有,并且不在绑定了排除验证场景的,置真。就是说这些是需要验证的。
46         //检查有绑定场景,则将这些置真来验证,其他的不验证。
47         foreach ($this->getValidators() as $validator) {
48             if (empty($validator->on) && empty($validator->except)) {
49                 foreach ($names as $name) {
50                     //rules中没有指定on和except,那$names就只有default
51                     //此时会将验证器上所有的属性循环到$scenarios['default']中去。
52                     //意即所有的属性在所有场景都要验证
53                     foreach ($validator->attributes as $attribute) {
54                         $scenarios[$name][$attribute] = true;
55                     }
56                 }
57             } elseif (empty($validator->on)) {
58                 //rules中on为空,except设置
59                 foreach ($names as $name) {
60                     //不在except中,并且在rules中,在场景中设置真。不在场景中的根本不进入这个验证列表。
61                     //结果还是留下default,实际情况也是如此,所有场景都不验证,符合逻辑
62                     if (!in_array($name, $validator->except, true)) {
63                         foreach ($validator->attributes as $attribute) {
64                             $scenarios[$name][$attribute] = true;
65                         }
66                     }
67                 }
68             } else {
69                 //这里会留下on绑定的场景的属性。除外的就被排除了。
70                 foreach ($validator->on as $name) {
71                     foreach ($validator->attributes as $attribute) {
72                         $scenarios[$name][$attribute] = true;
73                     }
74                 }
75             }
76         }
77 
78         //上面是跟rules所限定的验证器比对,在的并符合需要验证条件的置真。
79         //然后与场景list中的设置进行比较,过滤调场景中没有的属性
80         foreach ($scenarios as $scenario => $attributes) {
81             if (!empty($attributes)) {
82                 $scenarios[$scenario] = array_keys($attributes);
83             }
84         }
85 
86         return $scenarios;
87     }

 

 1 /**
 2      * Returns the validators applicable to the current [[scenario]].
 3      * @param string $attribute the name of the attribute whose applicable validators should be returned.
 4      * If this is null, the validators for ALL attributes in the model will be returned.
 5      * @return \yii\validators\Validator[] the validators applicable to the current [[scenario]].
 6      */
 7     public function getActiveValidators($attribute = null)
 8     {
 9         $validators = [];
10         $scenario = $this->getScenario();
11         foreach ($this->getValidators() as $validator) {
12             if ($validator->isActive($scenario) && ($attribute === null || in_array($attribute, $validator->getAttributeNames(), true))) {
13                 $validators[] = $validator;
14             }
15         }
16         return $validators;
17     }

以上返回应用到当前场景的验证器,$attribute指定要返回的验证器属性名。如果为null,所有的都返回。这里先获取到场景名,默认是default,然后循环当前model上的验证器,如果在

当前这个场景验证器活跃,并且传入的属性为null,或者该属性存在于验证器上,写入验证器数组。

 1 /**
 2      * Returns a value indicating whether the validator is active for the given scenario and attribute.
 3      *
 4      * A validator is active if
 5      *
 6      * - the validator's `on` property is empty, or
 7      * - the validator's `on` property contains the specified scenario
 8      *
 9      * @param string $scenario scenario name
10      * @return bool whether the validator applies to the specified scenario.
11      */
12     public function isActive($scenario)
13     {
14         return !in_array($scenario, $this->except, true) && (empty($this->on) || in_array($scenario, $this->on, true));
15     }

返回一个代表验证器在给定场景和属性上是否激活。激活的判断标准是,验证器的on属性为空,或者on属性包含指定的场景。

 1 /**
 2      * Returns cleaned attribute names without the `!` character at the beginning
 3      * @return array attribute names.
 4      * @since 2.0.12
 5      */
 6     public function getAttributeNames()
 7     {
 8         return array_map(function($attribute) {
 9             return ltrim($attribute, '!');
10         }, $this->attributes);
11     }

在开始返回不带有!的干净的属性名。

 

 1 /**
 2      * Validates the specified object.
 3      * @param \yii\base\Model $model the data model being validated
 4      * @param array|null $attributes the list of attributes to be validated.
 5      * Note that if an attribute is not associated with the validator - it will be
 6      * ignored. If this parameter is null, every attribute listed in [[attributes]] will be validated.
 7      */
 8     public function validateAttributes($model, $attributes = null)
 9     {
10         if (is_array($attributes)) {
11             $newAttributes = [];
12             foreach ($attributes as $attribute) {
13                 if (in_array($attribute, $this->getAttributeNames(), true)) {
14                     $newAttributes[] = $attribute;
15                 }
16             }
17             $attributes = $newAttributes;
18         } else {
19             $attributes = $this->getAttributeNameas();
20         }
21 
22         foreach ($attributes as $attribute) {
23             $skip = $this->skipOnError && $model->hasErrors($attribute)
24                 || $this->skipOnEmpty && $this->isEmpty($model->$attribute);
25             if (!$skip) {
26                 if ($this->when === null || call_user_func($this->when, $model, $attribute)) {
27                     $this->validateAttribute($model, $attribute);
28                 }
29             }
30         }
31     }

验证的核心代码,验证指定的对象,参数$model是被验证的数据模型,$attributes要被验证的属性列表,如果他没有关联的到验证器就忽略,如果该参数为null,所有的属性都将被验证。

如果是数组,定义一个空数组,并对该数组循环,传入的就是该活跃场景下所有属性,一般为default,全部。场景中的属性如果不在验证器里面,就忽略掉,不存入新数组,如果不是数组,

就直接从验证器上取出属性。

 $skip = $this->skipOnError && $model->hasErrors($attribute)|| $this->skipOnEmpty && $this->isEmpty($model->$attribute);

定义的$this->skipOnError默认为真,$this->skipOnEmpty也为真,其他两个就是检测是否有错或者空。前两个和后两个合成的结果可以有一个为假,但必须同时为假,已经有两个属性默认为真的,那前后两个其他属性必须都为假,就是说该被验证的属性既不能为空,也不能有错。

转载于:https://www.cnblogs.com/jiangtian/p/8311066.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/414889.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端学习(2697):重读vue电商网站18之监听图片删除事件

Js // 处理图片移除的操作 handleRemove(file) {// 1.获取将要删除的图片的临时路径const filePath file.response.data.tmp_path// 2.从pics数组中,找到这个图片对应的索引值const idx this.addForm.pics.findIndex(x > x.pic filePath)// 3.调用数组的 spli…

vscode开发java接口跳转到实现

我是mac系统,按照默认是commandF12,但是我的mac 13寸,按照这个快捷键,就显示亮度调节了。所以需要使用插件IntelliJ IDEA Keybindings来解决这个问题。 快捷方式如下:

前端学习(2698):重读vue电商网站19之处理图片预览操作

图片预览窗可以用 el-dialog 组件来做&#xff0c;然后通过 on-preview 函数来处理图片预览的操作。 Js <!-- 图片预览 --> <el-dialog title"图片预览" :visible.sync"previewVisable" width"50%"><img :src"previewPath&…

Android 集成高德地图——当前定位,添加图标,画路线,设置显示中心位置,比例,地图刷新位置监听,判断GPS开启,去打开GPS

/*** 判断定位服务是否开启** param* return true 表示开启*/ public static boolean isLocationEnabled(Context context) {int locationMode 0;String locationProviders;if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {try {locationMode Settings.Secure.…

vscode-spring-boot YAML_UNKNOWN_PROPERTY 解决

使用vscode开发&#xff0c;安装了vscode-spring-boot ,报错如下 解决方案&#xff0c;增加对yml文件的识别 新增.vscode/settings.json 内容如下&#xff1a; {"files.associations": {"*.yml": "yaml"} }

Android之Junit测试类

今天跟着视频学习了Junit测试类&#xff0c;趁热打铁、顺便把学的东西整理下来&#xff0c;再就是为了以后好回顾 1、Junit单元测试介绍&#xff1a; 在实际开发中&#xff0c;经常要对已经实现的功能进行单元测试&#xff0c;以保证当前单元没问题&#xff0c;尽可能的减少已有…

前端学习(2699):重读vue电商网站20之使用Timeline 时间线

可视化地呈现时间流信息。 由于 vue-cli-plugin-element 最后更新时间是 2019年1月&#xff0c;而 element-ui 中 Timeline 时间线更新是在 3月份&#xff0c;因此我们没有办法直接进行引用。因此&#xff0c;我们直接通过手动导入的方式。 然后&#xff0c;我们打开 element.j…

Android 高德地图根据地址获取经纬度,计算两个坐标的距离

1、到高德开放平台申请&#xff0c;获取key 高德开放平台&#xff1a;https://lbs.amap.com/ 2、下载高德定位及地址搜索SDK:https://download.csdn.net/download/meixi_android/10845407 3、项目绑定高德SDK &#xff08;1&#xff09;配置key <meta-data android:name&q…

Android中WebService的应用

1.简介 Android中的WebService 是一种基于SOAP协议的远程调用标准。通过WebService可以将不同操作系统平台&#xff0c;不同语言、不同技术整合到一起。在Android SDK中并没有提供调用WebService的库&#xff0c;因此&#xff0c;需要使用第三方类库&#xff08;KSOAP2&#x…

宝塔 nginx 配置文件的存放目录配置vue的history模式

在项目中使用vue的history模式&#xff0c;需要配置文件&#xff0c;使用到宝塔面板的服务器。现在记录存放位置。 /www/server/panel/vhost/nginx配置history模式 try_files $uri $uri/ /index.html qkbim/index.html;配置跨域 add_header Access-Control-Allow-Origin *;ad…

查看Chome浏览器中已保存的密码

好累啊&#xff0c;今天上午模拟比赛&#xff0c;敲了一上午的代码&#xff0c;真是够够的&#xff1b;想想自己自学Java&#xff0c;然后自学Android&#xff0c;到现在一直没有放弃&#xff0c;其中要感激的人有很多很多&#xff0c;指导老师等等&#xff0c;最感谢的还是现在…

vscode开发java自定义代码模版

1、打开首选项配置 2、选择全局的 3、填写自己的代码块 {// Place your 全局 snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and // description. Add comma separated ids of the languages where the snippet is applicable…

前端学习(2702):重读vue电商网站23之element-ui 如何按需导入

在element.js 文件中&#xff0c;按照如下方式&#xff0c;进行按需导入即可。然后通过 Vue.use()方法进行引用。&#xff08;优化点&#xff1a;也就是将组建导入都放在一起&#xff0c;如果组件过多的话&#xff0c;支持换行&#xff09;

Socket实现Android客户端与服务器的通信

前言&#xff1a;题目要求故写一下总结。 1.什么是Socket? 网络用语叫套接字原理是基于tcp/ip 协议的一种通信手段&#xff0c;目前题目中要求无非就是当客户端数据异常时推送给服务器报警信息 往常接下来都是先看效果图的&#xff0c;由于今天回宿舍有点早&#xff0c;准备有…

完成聊天室的私聊功能

1 完成聊天室的私聊功能 完成聊天室私聊功能。私聊功能是指&#xff0c;客户端之间可以实现一对一的聊天。 服务器端程序启动后&#xff0c;将等待客户端连接&#xff0c;界面效果如图&#xff0d;1所示&#xff1a; 图&#xff0d;1 客户端程序运行时&#xff0c;需要用户先输…

高德地图跟百度地图经纬度互转

1、高德经纬度转百度经纬度&#xff1a; "http://api.map.baidu.com/geoconv/v1/?coords"endlo","endla"&from3&to5&ak""Hi7RspVbu9xQNVUi0S7iP0OLLQbNfn""&mcode07:63:0A:B5:14:92:C6:95:43:8C:5E:78:1D:27:27…

前端学习(2703):重读vue电商网站24之配置axios

在 main.js 文件内进行配置 那么&#xff0c;此时我们就可以通过 this访问登录组件原型上 $http 方法&#xff0c;来发起对后端的请求了。

StudentManager-java+mysql学生管理系统

哎&#xff0c;还是没坚持写下来&#xff0c;时间过得也好快&#xff0c;转眼大二上学期就要结束了&#xff0c;算了&#xff0c;先附上几天写的java-mysql学生管理系统吧 先看效果图吧&#xff0c;没录动态图&#xff0c;将就着看吧 1.程序登陆&#xff0c;初始界面 2.根据名字…

message:MCODE参数不存在,mobile类型mcode参数必需

是不是高德地图转百度地图经纬度报错 问题是缺少mcode参数——也就是缺少安全码 解决方法&#xff1a;https://blog.csdn.net/meixi_android/article/details/84987062