sxsnwangrenfei

sxsnwangrenfei 查看完整档案

填写现居城市  |  填写毕业院校  |  填写所在公司/组织填写个人主网站
编辑
_ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 该用户太懒什么也没留下

个人动态

sxsnwangrenfei 提出了问题 · 11月21日

Chrome 打印PDF 如何保持页面跳转链接?

在打印HTML为PDF时,发现html里面的锚点链接失效。
如何写这个链接才能让导出的PDF里能正常跳转页面?

关注 1 回答 0

sxsnwangrenfei 提出了问题 · 4月23日

js 监听页面关闭 onbeforeunload,可以监听到点了确定还是取消吗?

window.onbeforeunload = function(e) {
    var e = window.event || e;
    e.returnValue = ("您可能有未保存的内容,确定离开当前编辑器页面吗?");
}

这个方法,能否监听到,用户点了确定还是取消?
我需要确定后删除一下cookie,取消的话不删除。

关注 1 回答 0

sxsnwangrenfei 关注了标签 · 2019-10-31

thinkphp

ThinkPHP是一个开源的PHP框架,是为了简化企业级应用开发和敏捷WEB应用开发而诞生的。最早诞生于2006年初,原名FCS,2007年元旦正式更名为ThinkPHP,并且遵循Apache2开源协议发布。早期的思想架构来源于Struts,后来经过不断改进和完善,同时也借鉴了国外很多优秀的框架和模式,使用面向对象的开发结构和MVC模式,融合了Struts的Action和Dao思想和JSP的TagLib(标签库)、RoR的ORM映射和ActiveRecord模式,封装了CURD和一些常用操作,单一入口模式等,在模版引擎、缓存机制、认证机制和扩展性方面均有独特的表现。

关注 646

sxsnwangrenfei 提出了问题 · 2019-10-31

新手问题,thinkphp每秒请求100次,需要多大内存?

我有个项目,目前最大每秒请求数100多次,原来是原生PHP写的,目录比较乱,想换成TP6的。

但是测试了下TP6,空白页面都比我原生的慢10倍以上,内存占用大数十万倍以上。

TP6的:运行速度:0.082156s,内存消耗:3,321.66kb(加载134个文件)
原生的:运行速度:0.012267s,内存消耗:0.0004kb(加载3-4个文件)

服务器是8核12G内存,现在是怕换TP6后,内存爆满,服务器压力增大,网站速度明显变慢。

由于不知道内存是如何计算的,一个请求3M内存,每秒100个并发请求是不是占300M内存?或者累加的更大?

麻烦大家给个建议,划得来换TP框架吗?

关注 2 回答 2

sxsnwangrenfei 提出了问题 · 2019-10-30

ThinkPHP6 原生PHP模板引擎如何include?

TP6默认没装模板引擎,我打算直接不用模板引擎了,
但是

include 'view/common/header.php';

明明有这个文件,提示没有这个文件,应该如何引入呢?

原模板写法是:

{include file="common/head"}

原生写法怎么写?

关注 2 回答 2

sxsnwangrenfei 关注了标签 · 2019-10-16

ueditor

UEditor是由百度WEB前端研发部开发的所见即所得的开源富文本编辑器,具有轻量、可定制、用户体验优秀等特点。开源基于BSD协议,所有源代码在协议允许范围内可自由修改和使用。百度UEditor的推出,可以帮助不少网站开发者在开发富文本编辑器所遇到的难题,节约开发者因开发富文本编辑器所需要的大量时间,有效降低了企业的开发成本。

官网:UEditor官网
Github:UEditor in Github

关注 26

sxsnwangrenfei 提出了问题 · 2019-10-15

解决Token方式防御CSRF攻击,当打开多个页面,前面的页面Token失效怎么办?

//test.php
<?php
session_start();
$token = base64_encode(openssl_random_pseudo_bytes(32));
$_SESSION['token'] = $token;
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>csrf demo</title>
</head>
<body>
    <form action="token.php" method="POST">
        <input type="hidden" name="token" value="<?= $token ?>">
        <input type="submit" value="Submit">
    </form>
</body>
</html>
// token.php
<?php
session_start();
if ($_SERVER['REQUEST_METHOD'] == 'POST' and (! isset($_POST['token']) || $_POST['token'] == $_SESSION['token'])) {
    echo 'request success';
} else {
    echo 'csrf forbidden';
}

Token方式防御csrf攻击,当打开多个页面,前面的页面表单失效怎么办?有没有什么简单方法能让之前的Token有效,并能有效防御csrf攻击?

关注 1 回答 1

sxsnwangrenfei 提出了问题 · 2019-10-12

解决MySQL,3306端口封闭后,网站还能打开吗?

百度云观测提示:MySQL,3306端口,内部敏感服务对外开放存在风险,容易引起安全问题

服务器上装的有云锁,云锁里面有个一键封闭mysql端口的功能,不知道能不能点?点了后会不会网站直接打不开了?

TIM截图20191011201735.jpg

TIM截图20191011201754.jpg

关注 2 回答 2

sxsnwangrenfei 收藏了文章 · 2019-09-18

js获取剪切板内容,js控制图片粘贴。

在用户执行粘贴操作的时候,js能够获得剪切板的内容,本文讨论一下这个问题。

目前只有Chrome支持获取剪切板中的图片数据。还好需要这个功能的产品目前只支持ChromeSafari,一些Chrome的新特性是可以尽情使用了,还是能够覆盖到大部分用户的。所以本文只讨论Chrome如何使用和如何阻止Safari,原理大概了解了,再研究其他浏览器相关的问题就容易多了。

paste事件

可以用js给页面中的元素绑定paste事件的方法,当用户鼠标在该元素上或者该元素处于focus状态,绑定到paste事件的方法就运行了。

绑定的元素不一定是input,普通的div也是可以绑定的,如果是给document绑定了,就相当于全局了,任何时候的粘贴操作都会触发。

事件对象

获取事件对象

先写一下事件绑定的代码

pasteEle.addEventListener("paste", function (e){
    if ( !(e.clipboardData && e.clipboardData.items) ) {
        return;
    }
});

粘贴事件提供了一个clipboardData的属性,如果该属性有items属性,那么就可以查看items中是否有图片类型的数据了。Chrome有该属性,Safari没有。

clipboardData介绍

介绍一下clipboardData对象,它实际上是一个DataTransfer类型的对象,DataTransfer 是拖动产生的一个对象,但实际上粘贴事件也是它。

clipboardData的属性介绍

属性类型说明
dropEffectString默认是 none
effectAllowedString默认是 uninitialized
filesFileList粘贴操作为空List
itemsDataTransferItemList剪切板中的各项数据
typesArray剪切板中的数据类型 该属性在Safari下比较混乱

items介绍

items是一个DataTransferItemList对象,自然里面都是DataTransferItem类型的数据了。

属性

itemsDataTransferItem有两个属性kindtype

属性说明
kind一般为string或者file
type具体的数据类型,例如具体是哪种类型字符串或者哪种类型的文件,即MIME-Type

方法

方法参数说明
getAsFile如果kindfile,可以用该方法获取到文件
getAsString回调函数如果kindstring,可以用该方法获取到字符串,字符串需要用回调函数得到,回调函数的第一个参数就是剪切板中的字符串

在原型上还有一些其他方法,不过在处理剪切板操作的时候一般用不到了。

types介绍

一般types中常见的值有text/plaintext/htmlFiles

说明
text/plain普通字符串
text/html带有样式的html
Files文件(例如剪切板中的数据)

简单demo

pasteEle.addEventListener("paste", function (e){
    if ( !(e.clipboardData && e.clipboardData.items) ) {
        return ;
    }

    for (var i = 0, len = e.clipboardData.items.length; i < len; i++) {
        var item = e.clipboardData.items[i];

        if (item.kind === "string") {
            item.getAsString(function (str) {
                // str 是获取到的字符串
            })
        } else if (item.kind === "file") {
            var pasteFile = item.getAsFile();
            // pasteFile就是获取到的文件
        }
    }
});

注意如果是string类型的数据,可能针对具体是text/plaintext/html进行分别的处理。

问题来了

一切看似都很顺利,如果用户粘贴了图片,通过上面的方法我们是可以获取到,可以对图片进行上传等操作了。

首先要说一下js通过剪切板能获取到的图片是怎么来的,它必须是用QQ截图或者系统截图功能截下来的图片,或者是网页上某个图片单击右键复制图片等。

但是如果用户复制MacFinder中的一个图片文件,实际上js是没有办法获取到这个图片的。但是js确实会获得一个图片类型的文件,这个图片实际上图片在电脑中的图标标识,说的比较抽象,直接上图。

图片描述

如果复制的是JPEG图片,粘贴过来的却是Mac上的文件缩略图,后面依次是PNGGIFZIPDMGMac目录的文件缩略图。

很明显,这不是我们期待得到的粘贴的结果,我们期待得到文件,但实际上却得到该文件在操作系统上的缩略图。

不过粘贴事件带来的数据还有一个字符串,就是该文件的名字,所以可以用下面的方法Hack掉。

    var cbd = e.clipboardData;
    if(cbd.items && cbd.items.length === 2 && cbd.items[0].kind === "string" && cbd.items[1].kind === "file" &&
            cbd.types && cbd.types.length === 2 && cbd.types[0] === "text/plain" && cbd.types[1] === "Files"){
        return;
    }

这么多的判断条件,基本可以确定通过剪切板过来的是粘贴的文件。我刚才测试了WindowsChrome,不会有这个问题,当然也不能通过复制文件的方法得到任何文件。

问题又来了

当我打算写这篇博客的时候,Chrome开发版已经升级到了49,上面的Bug突然消失了,囧。
所以上面的Hack应该加上版本限制了。

var ua = window.navigator.userAgent;
ua.match(/Macintosh/i) && Number(ua.match(/Chrome\/(\d{2})/i)[1]) < 49

应该在上面的Hack再加上这两个判断,即是Mac下的Chrome49版本以下就要return

探究过程走的一点弯路

由于公司IM系统正在迁移到V2消息系统,而且现有的文件类库没有办法满足业务需求,要自己封装一个文件上传库。

然后副总找到产品经理,说新版怎么不支持Excel的粘贴,临时排期一天修复这个问题,当时是这样解决的,如果items长度是1并且是文件类型(单纯粘贴一个文件),则上传,如果items长度是4且第4个是文件类型(经过测试是Excel的粘贴结果),则上传。

当时担心由于用户各种误操作,粘贴了不该粘贴的东西,文件上传错误,用了这种白名单机制去过滤,但是万一以后有比Excel粘贴得到的数据更其他的类型,就需要单独写代码兼容,所以,现在改成了如果判断是有Bug的情况,直接return,属于黑名单机制,这样以后再发现黑名单的情况,再添加。

可以拿来就用的代码

// demo 程序将粘贴事件绑定到 document 上
document.addEventListener("paste", function (e) {
    var cbd = e.clipboardData;
    var ua = window.navigator.userAgent;

    // 如果是 Safari 直接 return
    if ( !(e.clipboardData && e.clipboardData.items) ) {
        return;
    }
    
    // Mac平台下Chrome49版本以下 复制Finder中的文件的Bug Hack掉
    if(cbd.items && cbd.items.length === 2 && cbd.items[0].kind === "string" && cbd.items[1].kind === "file" &&
        cbd.types && cbd.types.length === 2 && cbd.types[0] === "text/plain" && cbd.types[1] === "Files" &&
        ua.match(/Macintosh/i) && Number(ua.match(/Chrome\/(\d{2})/i)[1]) < 49){
        return;
    }

    for(var i = 0; i < cbd.items.length; i++) {
        var item = cbd.items[i];
        if(item.kind == "file"){
            var blob = item.getAsFile();
            if (blob.size === 0) {
                return;
            }
            // blob 就是从剪切板获得的文件 可以进行上传或其他操作
        }
    }
}, false);
查看原文

sxsnwangrenfei 提出了问题 · 2018-12-28

解决JQ定义css时,键名可以使用变量吗?

if(...){
    a="left";
}else{
    a="right";
}

obj.css({
    a:"20px"
})

如上,上面的做法并不生效,有没有什么办法可以让这个a是个变量呢?
由于情况复杂,所以得这样做,能省去大量的麻烦。有人知道这个能实现吗?

关注 2 回答 1

认证与成就

  • 获得 1 次点赞
  • 获得 27 枚徽章 获得 0 枚金徽章, 获得 4 枚银徽章, 获得 23 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2016-11-16
个人主页被 500 人浏览