笔记

28
Jul

记一次node-gyp和python版本冲突解决

很多前端框架自带的依赖会依赖早期的node-gyp
然而早期版本node-gyp有个严重问题就是不支持python3。如果客户端没有安装python2或者说python2有问题,在npm install时就会出现如下错误

gyp ERR! stack Error: Command failed: /Users/nick/anaconda3/bin/python3 -c import sys; print "%s.%s.%s" % sys.version_info[:3];

解决方法就是手动更新node-gyp到最新版

npm update -g node-gyp@latest

如果项目内依赖有node-gyp,就需要做很复杂的依赖管理去升级。

很多node-gyp的依赖时node-sass导致的,node-sass的新版已经不再依赖node-gyp,同时node-sass老版的编译与node 16.0以上的版本不兼容,如果出现一些其他的gyp错误,把node降到14、15的版本就可以解决

04
May

Table '.\mysql\proxies_priv' is marked as crashed and last (automatic?) repair failed

如果是windows下xampp启动mysql失败导致类似的错误
通过事件查看器发现的日志显示这个表出问题

建议放弃修复,这应该是一个偶发的数据索引错乱

https://community.apachefriends.org/f/viewtopic.php?t=79199
https://stackoverflow.com/questions/8843776/mysql-table-is-marked-as-crashed-and-last-automatic-repair-failed

可以直接去xampp目录/mysql/data/mysql下把所有proxies_priv的文件删掉。
理论上不影响什么,毕竟proxy_user功能基本没人用

16
Mar

Crontab 不执行php/laravel等命令

可能的原因:php有多个版本,cron的php命令指向不能识别。
cron在执行php的时候和手动在终端调用php不一样,可能是由root用户发起,因此他会根据当前用户来选择全局环境变量
比如如下脚本无效

* * * * * php /www/somescripts.php

应该改为

* * * * * /usr/local/bin/php /www/somescripts.php

可以通过whereis php等命令找到所需的php

25
Feb

Laravel 明明有csrf_token仍然报419 token mismatch错误

一个可能的原因是,因为项目的正式端和测试端(开发端也有可能)的.env中间配置的APP_NAME相同(或者都为纯中文),导致cookies的键相同,进而导致session冲突。

原理:laravel的cookies键产生位于config/session.php

'cookie' => env(
    'SESSION_COOKIE',
    Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
 ),

如果.env中间没有配置SESSION_COOKIE这一项(默认没有),那么cookies键会由APP_NAME格式化字符串生成,因为本土化原因中文会被删掉,所以如果两个站点的APP_NAME相同,比如都是xxwebsite,那么产生的键都是xxwebsite_session,如果都是中文的话,那么更会导致键直接是_session,引发更严重的跨站冲突。

解决方案:修改APP_NAME为不同的非中文字符串,或者为不同项目的.env中配置不同的SESSION_COOKIE字段。

参考文章

21
Jun

乱域-LZR第四代特效素材包更新

版权声明

  • 禁止未经许可对本特效包的分发、修改等。作者QQ:1010086485
  • 目前V4特效包仍处于内测阶段,禁止未经许可将其使用于正式项目(如solo、正式联合等)
  • 欢迎对特效需求等提出相关意见

下载:(6月21日更新)
LZR第四代特效素材包-0621测试
LZR第四代特效素材包-0612测试

注:素材包使用Adobe Animate cc制作,理论上CS6可以转码使用,但是可能丢失数据。尽量使用Adobe Animate cc系列软件。

29
Nov

ElasticSearch 配置Logstash导入mysql数据库

网上教程不少,但是大多对新手不太友好,细节也不太好,这里针对ElasticSearch小白。

以ElasticSearch 5.6.12 和 LogStash 5.6.13为例。这两个的安装从略。
尽量保证两者版本不要相差太多。考虑到LogStash只作为管道,版本不需要一致。

先到LogStash目录下安装JDBC插件

cd /opt/logstash
bin/plugin install logstash-input-jdbc

如果是windows下,请自行在可执行文件后加上.bat

安装完之后开始导入,这个导入过程我们编写一个conf文件实现,这里以logstash.conf为例,为了方便可以直接在logstash/bin下创建一个logstash.conf

input {
  jdbc { 
    # "your-database" 是数据库名    
    jdbc_connection_string => "jdbc:mysql://localhost:3306/your-database"  
    #mysql数据库用户名密码
    jdbc_user => "root" 
    jdbc_password => "********"
    #schedule 可选,如果有schedule则会自动同步,这里意思是每一分钟同步一次,没有就只同步一次。具体的见官方文档
    #schedule => "* * * * *"
    #这里需要使用一个mysql连接库,文末有下载地址,自行下载后随便放一个地方,这里只是举例
    jdbc_driver_library => "/usr/local/logstash/mysql-connector-java-6.0.5.jar"
    jdbc_driver_class => "com.mysql.jdbc.Driver"
    #查询,这里只需要select一下即可,比如从your-schema数据表
    statement => "SELECT * FROM `your-schema`"
    }
  }
output {
  stdout { codec => json_lines }
  elasticsearch {
  "hosts" => "localhost:9200"
  #your-index是事件要被写进的索引 如果没有索引就新建一个
  "index" => "your-index"
  #your-type-name 只是数据集的分类,自定义,同类数据尽量使用同一个type
  "document_type" => "your-type-name"
  #可选,这里的意思是绑定原mysql表的id列作为主键,可以避免重复
  "document_id" => "%{id}"
  }
}

然后执行

cd /opt/logstash/bin
./logstash -f logstash.conf

可以看到一排输出,然后数据就注入成功了。

顺带一提,如果小白注入完数据发现有unassigned数据,或者说集群健康度不够,是因为现在的节点分片不够存储数据集的1份备份(默认一份)。只需要执行诸如

curl -XPUT 'localhost:9200/your-index/_settings' -d '{"number_of_replicas": 0}'

将备份数降低即可。

一个可用的Maven的mysql-connector-java-6.0.5.jar

24
Nov

lnmp配置laravel/thinkphp时出现no input file specified的常见问题

lnmp的域名绑定命令即使到最新的1.5版都是一套不太成熟的做法。
我们每次执行诸如lnmp vhost add时,都会在目录下生成一个类似这样的.user.ini文件

open_basedir=/home/wwwroot/your-project/:/tmp/:/proc/

.user.ini的作用是覆写php.ini中的部分参数,在这里来说,open_basedir在php.ini中可能有一个全局值,而在这个目录下有一个局部的值会覆盖全局值。

而open_basedir则是造成nginx/php-fpm 报错的罪魁祸首,这么说可能不恰当,因为.user.ini的本意是好的,其机理是限制php访问目录,举例来说,你在这个目录下配置的php文件只能操作/home/wwwroot/your-project/下的文件。

而这样就导致了我们在使用诸如laravel/ThinkPHP框架时的问题。比如我们在home/wwwroot下建立了名为your-project的laravel项目,但是lnmp绑定vhost时,按常理是要绑定到/public目录下的。因为/public下是整个网站的入口,这样一来就产生问题了:.user.ini中会生成/home/wwwroot/your-project/public/:/tmp/:/proc/这样的参数,然而这个项目的php是必须要有要调用/public外文件的权限的!这个问题的产生往往会让人难以排查,因为不管是浏览器输出,亦或是nginx和php-fpm的log都不会给出任何错误信息,一个隐藏在/public下的.user.ini文件很难让新手发觉出问题。

解决方案:

.user.ini被安全锁定了,先使用

chattr -i .user.ini

将其解锁,然后vim编辑去掉/public,再chattr +i .user.ini加锁。
当然你也可以直接解锁后删掉,这样损失了一定安全性,对于小项目或者本地项目倒没什么意义了。

21
Oct

CMake编译Opencv时遇到的bug解决方案 windres.exe: unknown option -- W ... ; 'sprintf_instead_use_StringCbPrintfA_ was not declared in this scope ..

执行mingw32-make后

28%左右遇到这种错误:
... windres.exe: unknown option -- W ...

解决方案:
在cmake中 取消勾选 ENABLE_PRECOMPILED_HEADERS


32%左右遇到这种错误 :
'sprintf_instead_use_StringCbPrintfA_or_StringCchPrintfA' was not declared in this scope ...

解决方案:
在..\opencv\sources\modules\videoio\src\cap_dshow.cpp
在#include "DShow.h"这一行前加上#define NO_DSHOW_STRSAFE

20
Sep

Matlab App Designer UIFigure中利用dojo/js/Container/缩放/改图标等技巧

本文部分内容翻译于:Undocumented Matlab

Matlab AppDesigner是R2016a之后推出的新界面设计工具,较GUIDE的GUI 界面更美化,组建更丰富,具有自动化编程等特性。

但是表面上看AppDesigner并没有暴露很多组件诸如Javaframe

GUIDE的figure(gcf)是基于Java的Jframe组件,而Appdesigner的app.UIFigure是基于html的webview,本质上运行了一个CEF(Chromium嵌入式框架 Chromium Embedded Framework version 3.2272 on Chromium 41 in R2016a)。使用的JS DOJO 套件,可以想象Matlab与js/webapp接轨的趋势了。。

因此,如果像GUIDE一样或者其他教学一样视图获取

get(app.UIFigure,'javaframe')

会得到一个空数组,而且是特意留下的,Matlab一直有抛弃javaframe的想法,还发布过调查,现在看来还是不敢完全抛弃。

不说更多,下面就揭示一些其他组件结构吧。

阅读全文»

18
Jul

polyfill,shim,shiv之间有什么区别

什么是polyfill和shim

搜索了一下:在JavaScript的世界里,有两个词经常被提到,shim和polyfill.它们指的都是什么,又有什么区别?一个shim是一个库,它将一个新的API引入到一个旧的环境中,而且仅靠旧环境中已有的手段实现;一个polyfill就是一个用在浏览器API上的shim.我们通常的做法是先检查当前浏览器是否支持某个API,如果不支持的话就加载对应的polyfill.然后新旧浏览器就都可以使用这个API了。

理解

一个shim就是一个库,它将一个新的API引入到一个旧的环境中,而且仅靠旧环境中已有的手段实现。
比如ES5-shim, github地址:http://github.com/es-shims/es5-shim/

这几天看了一下shiv,它的作用是使得不支持HTML5标签的浏览器诸如ie6-8, 支持html5标签。这也是我在看html语义化规范的时候看到的,觉得很有必要做一下。目前使用IE8的用户还是占据一部分比例的,所以为了兼容ie8,同时能使用像header、section、nav、footer这些语义化标签,我们可以采用shiv库来实现。
著名的HTML5兼容库html5shiv,Github地址:https://github.com/aFarkas/html5shiv

关于polyfill,据说来自于Polyfilla,Polyfilla是一个英国产品,在美国称之为Spackling Paste(译者注:刮墙的,在中国称为腻子),把旧的浏览器想象成为一面有了裂缝的墙,这些polyfill会帮助我们把这面墙的裂缝抹平。

其实一个polyfill的意思就是,比如开发者想要一个格式化时间的函数,然后现有的api都没有,于是作者自创一个stringDate的方法,那么这个方法就成为一个polyfill。

问题

注意在实现polyfill的时候,最好不要在一些原生对象的原型上添加方法,比如:

if (!Array.prototype.find) {
        Array.prototype.find = function (predicate) {
            if (this === null)
                throw new TypeError('Array.prototype.find called on null or undefined');
            if (typeof predicate !== 'function')
                throw new TypeError('predicate must be a function');
            var list = Object(this);
            var length = list.length >>> 0;
            var thisArg = arguments[1];
            var value;
            for (var i = 0; i < length; i++) {
                value = list[i];
                if (predicate.call(thisArg, value, i, list))
                    return value;
            }
        }
    }

在IE下面有个bug,就是在使用 for in 这种循环的时候,ie下会遍历输出原型链上的方法,比如:

var a = [1,2];
for(var i in a){
    console.log(i);
}
//output
1
2
find

这就会导致bug。
查了一下can1use:

As the specification includes many JavaScript features, un-numbered partial support varies widely and is shown in detail on the ECMAScript 5 compatibilty tables by Kangax.
Does not support parseInt() ignoring leading zeros.
Does not support Strict mode
IE8 has virtually no ES5 support, but does support Object.defineProperty, Object.getOwnPropertyDescriptor, JSON parsing & Property access on strings
也就是说,在IE8下面支持Object.defineProperty这个方法,这个方法是直接给一个对象添加一个属性, 关键是可以控制是否能在for…in循环中遍历出来或在Object.keys中列举出来。如下:

Object.defineProperty(obj, prop, descriptor)将属性添加到对象,或修改现有属性的特性。
参数:
obj:目标对象
prop:需要定义的属性或方法的名字。
descriptor:目标属性所拥有的特性。
可供定义的特性列表:
value:属性的值
writable:如果为false,属性的值就不能被重写。
get: 一旦目标属性被访问就会调回此方法,并将此方法的运算结果返回用户。
set:一旦目标属性被赋值,就会调回此方法。
configurable:如果为false,则任何尝试删除目标属性或修改属性以下特性(writable, configurable, enumerable)的行为将被无效化。
enumerable:是否能在for...in循环中遍历出来或在Object.keys中列举出来。

 try{
        var a = {};
        Object.defineProperty(a,"bloger",{get:function(){return "司徒正美",value:"这是不可改变的默认值" ,writable: false}});
        alert(a.bloger)
      }catch(e){
        alert("你的游览器不支持Object.defineProperty ")
      }

所以我们可以通过这个方式修改Array.prototype,简单的实现方式:

Object.defineProperty(Array.prototype,"findT",{value:function(){return 1;}});

参考es5-shim中有一个自定义的defineProperties方法,

var defineProperties = (function (has) {
  // Define configurable, writable, and non-enumerable props
  // if they don't exist.
  var defineProperty;
  if (supportsDescriptors) {
      defineProperty = function (object, name, method, forceAssign) {
          if (!forceAssign && (name in object)) { return; }
          $Object.defineProperty(object, name, {
              configurable: true,
              enumerable: false,
              writable: true,
              value: method
          });
      };
  } else {
      defineProperty = function (object, name, method, forceAssign) {
          if (!forceAssign && (name in object)) { return; }
          object[name] = method;
      };
  }
  return function defineProperties(object, map, forceAssign) {
      for (var name in map) {
          if (has.call(map, name)) {
            defineProperty(object, name, map[name], forceAssign);
          }
      }
  };
}(ObjectPrototype.hasOwnProperty));

其实Object也是有defineProperties函数的,只是ie8不支持。

Object.defineProperties 函数 (JavaScript)
将一个或多个属性添加到对象,并/或修改现有属性的特性。

Object.defineProperties(obj, {
    newDataProperty: {
        value: 101,
        writable: true,
        enumerable: true,
        configurable: true
    },
    newAccessorProperty: {
        set: function (x) {
            document.write("in property set accessor" + newLine);
            this.newaccpropvalue = x;
        },
        get: function () {
            document.write("in property get accessor" + newLine);
            return this.newaccpropvalue;
        },
        enumerable: true,
        configurable: true
    }
});

谢谢!

转自:http://www.haomou.net/2016/10/22/2016_polyfill_shim/