找到
177
篇与
技术教程
相关的结果
- 第 17 页
-
HTTP(S)状态码详解教程 导读:当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头(server header)用以响应浏览器的请求。HTTP状态码常见于网站日志分析 (1)、HTTP状态码的英文为 HTTP Status Code。下面是常见的HTTP状态码: 200 – 请求成功 301 – 资源(网页等)被永久转移到其它URL 404 – 请求的资源(网页等)不存在 500 – 内部服务器错误 (2)、HTTP状态码的分类 HTTP状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。HTTP状态码共分为5种类型: 1** 信息,服务器收到请求,需要请求者继续执行操作 2** 成功,操作被成功接收并处理 3** 重定向,需要进一步的操作以完成请求 4** 客户端错误,请求包含语法错误或无法完成请求 5** 服务器错误,服务器在处理请求的过程中发生了错误 一、(1**)开头的状态码详解 100:客户端应当继续发送请求。这个临时响应是用来通知客户端它的部分请求已经被服务器接收,且仍未被拒绝。客户端应当继续发送请求的剩余部分,或者如果请求已经完成,忽略这个响应。服务器必须在请求完成后向客户端发送一个最终响应。 101:服务器已经理解了客户端的请求,并将通过Upgrade 消息头通知客户端采用不同的协议来完成这个请求。在发送完这个响应最后的空行后,服务器将会切换到在Upgrade 消息头中定义的那些协议。例如,切换到新的HTTP 版本比旧版本更有优势,或者切换到一个实时且同步的协议以传送利用此类特性的资源。 102:由WebDAV(RFC 2518)扩展的状态码,代表处理将被继续执行。 二、(2**)开头的状态码详解 200:请求已成功,请求所希望的响应头或数据体将随此响应返回。实际的响应将取决于所使用的请求方法。在GET请求中,响应将包含与请求的资源相对应的实体。在POST请求中,响应将包含描述或操作结果的实体。 201:请求已经被实现,而且有一个新的资源已经依据请求的需要而建立,且其 URI 已经随Location 头信息返回。假如需要的资源无法及时建立的话,应当返回 ‘202 Accepted’。 202:服务器已接受请求,但尚未处理。正如它可能被拒绝一样,最终该请求可能会也可能不会被执行。在异步操作的场合下,没有比发送这个状态码更方便的做法了。返回202状态码的响应的目的是允许服务器接受其他过程的请求(例如某个每天只执行一次的基于批处理的操作),而不必让客户端一直保持与服务器的连接直到批处理操作全部完成。在接受请求处理并返回202状态码的响应应当在返回的实体中包含一些指示处理当前状态的信息,以及指向处理状态监视器或状态预测的指针,以便用户能够估计操作是否已经完成。 203:服务器已成功处理了请求,但返回的实体头部元信息不是在原始服务器上有效的确定集合,而是来自本地或者第三方的拷贝。当前的信息可能是原始版本的子集或者超集。 204:服务器成功处理了请求,但不需要返回任何实体内容,并且希望返回更新了的元信息。响应可能通过实体头部的形式,返回新的或更新后的元信息。如果存在这些头部信息,则应当与所请求的变量相呼应。如果客户端是浏览器的话,那么用户浏览器应保留发送了该请求的页面,而不产生任何文档视图上的变化,即使按照规范新的或更新后的元信息应当被应用到用户浏览器活动视图中的文档。由于 204 响应被禁止包含任何消息体,因此它始终以消息头后的第一个空行结尾。 205:服务器成功处理了请求,且没有返回任何内容。但是与204响应不同,返回此状态码的响应要求请求者重置文档视图。该响应主要是被用于接受用户输入后,立即重置表单,以便用户能够轻松地开始另一次输入。 206:服务器已经成功处理了部分 GET 请求。类似于 FlashGet 或者迅雷这类的 HTTP 下载工具都是使用此类响应实现断点续传或者将一个大文档分解为多个下载段同时下载。 207:由 WebDAV(RFC 2518)扩展的状态码,代表之后的消息体将是一个XML消息,并且可能依照之前子请求数量的不同,包含一系列独立的响应代码。 三、(3**)开头的状态码详解 300:被请求的资源有一系列可供选择的回馈信息,每个都有自己特定的地址和浏览器驱动的商议信息。用户或浏览器能够自行选择一个首选的地址进行重定向。 301:被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个 URI 之一。 302:请求的资源现在临时从不同的URI响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。 303:对应当前请求的响应可以在另一个 URI 上被找到,而且客户端应当采用 GET 的方式访问那个资源。这个方法的存在主要是为了允许由脚本激活的POST请求输出重定向到一个新的资源。这个新的 URI 不是原始资源的替代引用。同时,303响应禁止被缓存。 304:如果客户端发送了一个带条件的GET请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码。 305:被请求的资源必须通过指定的代理才能被访问。Location 域中将给出指定的代理所在的 URI 信息,接收者需要重复发送一个单独的请求,通过这个代理才能访问相应资源。只有原始服务器才能建立305响应。 306:在最新版的规范中,306状态码已经不再被使用。 307:请求的资源现在临时从不同的URI响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。 四、(4**)开头的状态码详解 400:1、语义有误,当前请求无法被服务器理解。除非进行修改,否则客户端不应该重复提交这个请求。2、请求参数有误。 401:当前请求需要用户验证。该响应必须包含一个适用于被请求资源的 WWW-Authenticate 信息头用以询问用户信息。客户端可以重复提交一个包含恰当的Authorization头信息的请求。如果当前请求已经包含了 Authorization证书,那么401响应代表着服务器验证已经拒绝了那些证书。如果401响应包含了与前一个响应相同的身份验证询问,且浏览器已经至少尝试了一次验证,那么浏览器应当向用户展示响应中包含的实体信息,因为这个实体信息中可能包含了相关诊断信息。 402:该状态码是为了将来可能的需求而预留的。 403:服务器已经理解请求,但是拒绝执行它。与401响应不同的是,身份验证并不能提供任何帮助,而且这个请求也不应该被重复提交。 404:请求失败,请求所希望得到的资源未被在服务器上发现。没有信息能够告诉用户这个状况到底是暂时的还是永久的。 405:请求行中指定的请求方法不能被用于请求相应的资源。该响应必须返回一个Allow 头信息用以表示出当前资源能够接受的请求方法的列表。 406:请求的资源的内容特性无法满足请求头中的条件,因而无法生成响应实体。 407:与401响应类似,只不过客户端必须在代理服务器上进行身份验证。 408:请求超时。客户端没有在服务器预备等待的时间内完成一个请求的发送。客户端可以随时再次提交这一请求而无需进行任何更改。 409:由于和被请求的资源的当前状态之间存在冲突,请求无法完成。 410:被请求的资源在服务器上已经不再可用,而且没有任何已知的转发地址。 411:服务器拒绝在没有定义Content-Length头的情况下接受请求。在添加了表明请求消息体长度的有效 Content-Length头之后,客户端可以再次提交该请求。 412:服务器在验证在请求的头字段中给出先决条件时,没能满足其中的一个或多个。 413:服务器拒绝处理当前请求,因为该请求提交的实体数据大小超过了服务器愿意或者能够处理的范围。 414:请求的URI 长度超过了服务器能够解释的长度,因此服务器拒绝对该请求提供服务。 415:对于当前请求的方法和所请求的资源,请求中提交的实体并不是服务器中所支持的格式,因此请求被拒绝。 416:如果请求中包含了Range请求头,并且Range中指定的任何数据范围都与当前资源的可用范围不重合,同时请求中又没有定义 If-Range 请求头,那么服务器就应当返回416状态码。 417:在请求头 Expect中指定的预期内容无法被服务器满足,或者这个服务器是一个代理服务器,它有明显的证据证明在当前路由的下一个节点上,Expect 的内容无法被满足。 421:从当前客户端所在的IP地址到服务器的连接数超过了服务器许可的最大范围。 423:请求格式正确,但是由于含有语义错误,无法响应。 424:由于之前的某个请求发生的错误,导致当前请求失败,例如 PROPPATCH。 425:在WebDav Advanced Collections 草案中定义,但是未出现在《WebDAV 顺序集协议》(RFC 3658)中。 426:客户端应当切换到TLS/1.0。 449:由微软扩展,代表请求应当在执行完适当的操作后进行重试。 五、(5**)开头的状态码详解 500:服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。一般来说,这个问题都会在服务器的程序码出错时出现。 501:服务器不支持当前请求所需要的某个功能。当服务器无法识别请求的方法,并且无法支持其对任何资源的请求。 502:作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。 503:由于临时的服务器维护或者过载,服务器当前无法处理请求。这个状况是临时的,并且将在一段时间以后恢复。注意:503状态码的存在并不意味着服务器在过载的时候必须使用它。某些服务器只不过是希望拒绝客户端的连接。 504:作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到响应。 505:服务器不支持,或者拒绝支持在请求中使用的HTTP版本。这暗示着服务器不能或不愿使用与客户端相同的版本。响应中应当包含一个描述了为何版本不被支持以及服务器支持哪些协议的实体。 506:由《透明内容协商协议》(RFC 2295)扩展,代表服务器存在内部配置错误:被请求的协商变元资源被配置为在透明内容协商中使用自己,因此在一个协商处理中不是一个合适的重点。 507:服务器无法存储完成请求所必须的内容。这个状况被认为是临时的。WebDAV (RFC 4918) 509:服务器达到带宽限制。这不是一个官方的状态码,但是仍被广泛使用。 510:获取资源所需要的策略并没有没满足。(RFC 2774)
-
PHP获取网站标题、关键词与描述 PHP如何获取网站标题、关键词与描述呢? 在网页采集过程中,我们需要获取一个网站的meta信息,如title、keywords、description等,但是如果用普通的正则匹配很容易出错。那么到底该如何写这个PHP的代码,这篇文章为你带来解决方法。 使用get_meta_tags函数获取meta信息 比如我们要获取 http://blog.yihang.info 这个网页的meta信息,可以直接使用php内置函数get_meta_tags获取,代码如下: <?php $meta_tags = get_meta_tags("http://blog.yihang.info/"); print_r($meta_tags); ?>运行结果:你会发现获取了网页的关键词与描述,但是发现缺少了网页的标题,原因是标题并不是meta标签,而是组成的,所以我们的完整代码应该如下: /** 获取META信息 */ function get_sitemeta($url) { $data = file_get_contents($url); $meta = array(); if (!empty($data)) { #Title preg_match('/<TITLE>([\w\W]*?)<\/TITLE>/si', $data, $matches); if (!empty($matches[1])) { $meta['title'] = $matches[1]; } #Keywords preg_match('/<META\s+name="keywords"\s+content="([\w\W]*?)"/si', $data, $matches); if (empty($matches[1])) { preg_match("/<META\s+name='keywords'\s+content='([\w\W]*?)'/si", $data, $matches); } if (empty($matches[1])) { preg_match('/<META\s+content="([\w\W]*?)"\s+name="keywords"/si', $data, $matches); } if (empty($matches[1])) { preg_match('/<META\s+http-equiv="keywords"\s+content="([\w\W]*?)"/si', $data, $matches); } if (!empty($matches[1])) { $meta['keywords'] = $matches[1]; } #Description preg_match('/<META\s+name="description"\s+content="([\w\W]*?)"/si', $data, $matches); if (empty($matches[1])) { preg_match("/<META\s+name='description'\s+content='([\w\W]*?)'/si", $data, $matches); } if (empty($matches[1])) { preg_match('/<META\s+content="([\w\W]*?)"\s+name="description"/si', $data, $matches); } if (empty($matches[1])) { preg_match('/<META\s+http-equiv="description"\s+content="([\w\W]*?)"/si', $data, $matches); } if (!empty($matches[1])) { $meta['description'] = $matches[1]; } } return $meta; }
-
PHP图片上传代码 PHP上传图片完整实 HTML部分 <html> <head> <meta charset="utf-8"> <title>银狐笔记图片上传实例</title> </head> <body> <form action="up.php" method="post" enctype="multipart/form-data"> <label for="file">文件名:</label> <input type="file" name="file" id="file"><br> <input type="submit" name="submit" value="提交"> </form> </body> </html>form表单提交数据给PHP文件,enctype="multipart/form-data" ,这个代码不能少,获取文件类型。 PHP代码 <?php // 允许上传的图片后缀 $allowedExts = array("gif", "jpeg", "jpg", "png"); $temp = explode(".", $_FILES["file"]["name"]); echo $_FILES["file"]["size"]; $extension = end($temp); // 获取文件后缀名 if ( ( ($_FILES["file"]["type"] == "image/gif") || ($_FILES["file"]["type"] == "image/jpeg") || ($_FILES["file"]["type"] == "image/jpg") || ($_FILES["file"]["type"] == "image/pjpeg") || ($_FILES["file"]["type"] == "image/x-png") || ($_FILES["file"]["type"] == "image/png") ) && ($_FILES["file"]["size"] < 204800) // 小于 200 kb && in_array($extension, $allowedExts) ) { if ($_FILES["file"]["error"] > 0) { echo "错误:: " . $_FILES["file"]["error"] . "<br>"; } else { echo "上传文件名: " . $_FILES["file"]["name"] . "<br>"; echo "文件类型: " . $_FILES["file"]["type"] . "<br>"; echo "文件大小: " . ($_FILES["file"]["size"] / 1024) . " kB<br>"; echo "文件临时存储的位置: " . $_FILES["file"]["tmp_name"] . "<br>"; // 判断当前目录下的 upload 目录是否存在该文件 // 如果没有 upload 目录,你需要创建它,upload 目录权限为 777 if (file_exists("upload/" . $_FILES["file"]["name"])) { echo $_FILES["file"]["name"] . " 文件已经存在。 "; } else { // 如果 upload 目录不存在该文件则将文件上传到 upload 目录下 move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]); echo "文件存储在: " . "upload/" . $_FILES["file"]["name"]; } } } else { echo "非法的文件格式"; }
-
PHP万能Curl PHP完整实用Curl函数 PHP curl功能函数,请求网站那必须用curl,curl方法速度最快 这个curl函数功能非常全面了,可以请求99%的网站。 function curl($url, $paras = []) { $ch = curl_init(); if (isset($paras['Header'])) { $Header = $paras['Header']; } else { $Header[] = "Accept:*/*"; $Header[] = "Accept-Encoding:gzip,deflate,sdch"; $Header[] = "Accept-Language:zh-CN,zh;q=0.8"; $Header[] = "Connection:close"; } curl_setopt($ch, CURLOPT_HTTPHEADER, $Header); if (isset($paras['ctime'])) { // 连接超时 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $paras['ctime']); } else { curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); } if (isset($paras['rtime'])) { // 读取超时 curl_setopt($ch, CURLOPT_TIMEOUT, $paras['rtime']); } if (isset($paras['post'])) { curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $paras['post']); } if (is_array($paras['get'])) { $paras['get'] = http_build_query($paras['get']); $url = strstr($url, '?') ? trim($url, '&') . '&' . $paras['get'] : $url . '?' . $paras['get']; } if (isset($paras['header'])) { curl_setopt($ch, CURLOPT_HEADER, true); } if (isset($paras['cookie'])) { curl_setopt($ch, CURLOPT_COOKIE, $paras['cookie']); } if (isset($paras['refer'])) { if ($paras['refer'] == 1) { curl_setopt($ch, CURLOPT_REFERER, 'http://m.qzone.com/infocenter?g_f='); } else { curl_setopt($ch, CURLOPT_REFERER, $paras['refer']); } } if (isset($paras['ua'])) { curl_setopt($ch, CURLOPT_USERAGENT, $paras['ua']); } else { curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"); } if (isset($paras['nobody'])) { curl_setopt($ch, CURLOPT_NOBODY, 1); } curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_ENCODING, "gzip"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); if (isset($paras['GetCookie'])) { curl_setopt($ch, CURLOPT_HEADER, 1); $result = curl_exec($ch); preg_match_all("/Set-Cookie: (.*?);/m", $result, $matches); $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE); $header = substr($result, 0, $headerSize); //状态码 $body = substr($result, $headerSize); $ret = [ "Cookie" => $matches, "body" => $body, "header" => $header, 'code' => curl_getinfo($ch, CURLINFO_HTTP_CODE), ]; curl_close($ch); return $ret; } $ret = curl_exec($ch); if (isset($paras['loadurl'])) { $Headers = curl_getinfo($ch); if (isset($Headers['redirect_url'])) { $ret = $Headers['redirect_url']; } else { $ret = false; } } curl_close($ch); return $ret; }使用方法 GET访问 curl('http://blog.yihang.info');GET携带参数访问 curl('http://blog.yihang.info', [ 'get' => [ 'url' => 'blog.yihang.info' ] ]);POST访问 curl('http://blog.yihang.info', [ 'post' => [ 'url' => 'blog.yihang.info' ] ]);或者 curl('http://blog.yihang.info', [ 'post' => 'url=blog.yihang.info' ]);带Cookie curl('http://blog.yihang.info', [ 'cookie' => 'cookie内容' ]);模拟refer curl('http://blog.yihang.info', [ 'refer' => 'https://xxx' ]);模拟UA curl('http://blog.yihang.info', [ 'ua' => 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36' ]);上传文件 curl('http://blog.yihang.info', [ 'post' => [ 'file' => new CURLFile(realpath("Curl.jpg")) ] ]);或者 curl('http://blog.yihang.info', [ 'post' => new CURLFile(realpath("Curl.jpg")) ]);获取301地址 curl('http://blog.yihang.info', [ 'loadurl' => 1 ]);返回Header信息 curl('http://blog.yihang.info', [ 'header' => 1 ]);设置请求头 curl('http://blog.yihang.info', [ 'Header' => [ 'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3 accept-encoding: gzip, deflate, br accept-language: zh-CN,zh;q=0.9 cache-control: max-age=0' ] ]);获取请求的全部信息 curl('http://blog.yihang.info', [ 'post' => [ 'user' => 123456, 'pwd' => 123 ], 'GetCookie' => 1 ]);
-
PHP对字符串的六种加密解密方法 一、 function encryptDecrypt($key, $string, $decrypt) { if ($decrypt) { $decrypted = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode($string), MCRYPT_MODE_CBC, md5(md5($key))), "12"); return $decrypted; } else { $encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $string, MCRYPT_MODE_CBC, md5(md5($key)))); return $encrypted; } } //加密:"z0JAx4qMwcF+db5TNbp/xwdUM84snRsXvvpXuaCa4Bk=" echo encryptDecrypt('password', 'Helloweba欢迎您', 0); //解密:"Helloweba欢迎您" echo encryptDecrypt('password', 'z0JAx4qMwcF+db5TNbp/xwdUM84snRsXvvpXuaCa4Bk=', 1);二、 //加密函数 function lock_url($txt, $key = 'liiu') { $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-=+"; $nh = rand(0, 64); $ch = $chars[$nh]; $mdKey = md5($key . $ch); $mdKey = substr($mdKey, $nh % 8, $nh % 8 + 7); $txt = base64_encode($txt); $tmp = ''; $i = 0; $j = 0; $k = 0; for ($i = 0; $i < strlen($txt); $i++) { $k = $k == strlen($mdKey) ? 0 : $k; $j = ($nh + strpos($chars, $txt[$i]) + ord($mdKey[$k++])) % 64; $tmp .= $chars[$j]; } return urlencode($ch . $tmp); } //解密函数 function unlock_url($txt, $key = 'liiu') { $txt = urldecode($txt); $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-=+"; $ch = $txt[0]; $nh = strpos($chars, $ch); $mdKey = md5($key . $ch); $mdKey = substr($mdKey, $nh % 8, $nh % 8 + 7); $txt = substr($txt, 1); $tmp = ''; $i = 0; $j = 0; $k = 0; for ($i = 0; $i < strlen($txt); $i++) { $k = $k == strlen($mdKey) ? 0 : $k; $j = strpos($chars, $txt[$i]) - $nh - ord($mdKey[$k++]); while ($j < 0) $j += 64; $tmp .= $chars[$j]; } return base64_decode($tmp); }三、改进后的算法 //加密函数 function lock_url($txt, $key = 'str') { $txt = $txt . $key; $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-=+"; $nh = rand(0, 64); $ch = $chars[$nh]; $mdKey = md5($key . $ch); $mdKey = substr($mdKey, $nh % 8, $nh % 8 + 7); $txt = base64_encode($txt); $tmp = ''; $i = 0; $j = 0; $k = 0; for ($i = 0; $i < strlen($txt); $i++) { $k = $k == strlen($mdKey) ? 0 : $k; $j = ($nh + strpos($chars, $txt[$i]) + ord($mdKey[$k++])) % 64; $tmp .= $chars[$j]; } return urlencode(base64_encode($ch . $tmp)); } //解密函数 function unlock_url($txt, $key = 'str') { $txt = base64_decode(urldecode($txt)); $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-=+"; $ch = $txt[0]; $nh = strpos($chars, $ch); $mdKey = md5($key . $ch); $mdKey = substr($mdKey, $nh % 8, $nh % 8 + 7); $txt = substr($txt, 1); $tmp = ''; $i = 0; $j = 0; $k = 0; for ($i = 0; $i < strlen($txt); $i++) { $k = $k == strlen($mdKey) ? 0 : $k; $j = strpos($chars, $txt[$i]) - $nh - ord($mdKey[$k++]); while ($j < 0) $j += 64; $tmp .= $chars[$j]; } return trim(base64_decode($tmp), $key); }四、 function passport_encrypt($txt, $key = 'liiu') { srand((float)microtime() * 1000000); $encrypt_key = md5(rand(0, 32000)); $ctr = 0; $tmp = ''; for ($i = 0; $i < strlen($txt); $i++) { $ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr; $tmp .= $encrypt_key[$ctr] . ($txt[$i] ^ $encrypt_key[$ctr++]); } return urlencode(base64_encode(passport_key($tmp, $key))); } function passport_decrypt($txt, $key = 'liiu') { $txt = passport_key(base64_decode(urldecode($txt)), $key); $tmp = ''; for ($i = 0; $i < strlen($txt); $i++) { $md5 = $txt[$i]; $tmp .= $txt[++$i] ^ $md5; } return $tmp; } function passport_key($txt, $encrypt_key) { $encrypt_key = md5($encrypt_key); $ctr = 0; $tmp = ''; for ($i = 0; $i < strlen($txt); $i++) { $ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr; $tmp .= $txt[$i] ^ $encrypt_key[$ctr++]; } return $tmp; } $txt = "1"; $key = "testkey"; $encrypt = passport_encrypt($txt, $key); $decrypt = passport_decrypt($encrypt, $key); echo $encrypt . "<br>"; echo $decrypt . "<br>";五、非常给力的authcode加密函数,Discuz!经典代码(带详解) //函数authcode($string, $operation, $key, $expiry)中的$string:字符串,明文或密文;$operation:DECODE表示解密,其它表示加密;$key:密匙;$expiry:密文有效期。 function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) { // 动态密匙长度,相同的明文会生成不同密文就是依靠动态密匙 $ckey_length = 4; // 密匙 $key = md5($key ? $key : $GLOBALS['discuz_auth_key']); // 密匙a会参与加解密 $keya = md5(substr($key, 0, 16)); // 密匙b会用来做数据完整性验证 $keyb = md5(substr($key, 16, 16)); // 密匙c用于变化生成的密文 $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length)) : ''; // 参与运算的密匙 $cryptkey = $keya . md5($keya . $keyc); $key_length = strlen($cryptkey); // 明文,前10位用来保存时间戳,解密时验证数据有效性,10到26位用来保存$keyb(密匙b), //解密时会通过这个密匙验证数据完整性 // 如果是解码的话,会从第$ckey_length位开始,因为密文前$ckey_length位保存 动态密匙,以保证解密正确 $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string; $string_length = strlen($string); $result = ''; $box = range(0, 255); $rndkey = array(); // 产生密匙簿 for ($i = 0; $i <= 255; $i++) { $rndkey[$i] = ord($cryptkey[$i % $key_length]); } // 用固定的算法,打乱密匙簿,增加随机性,好像很复杂,实际上对并不会增加密文的强度 for ($j = $i = 0; $i < 256; $i++) { $j = ($j + $box[$i] + $rndkey[$i]) % 256; $tmp = $box[$i]; $box[$i] = $box[$j]; $box[$j] = $tmp; } // 核心加解密部分 for ($a = $j = $i = 0; $i < $string_length; $i++) { $a = ($a + 1) % 256; $j = ($j + $box[$a]) % 256; $tmp = $box[$a]; $box[$a] = $box[$j]; $box[$j] = $tmp; // 从密匙簿得出密匙进行异或,再转成字符 $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256])); } if ($operation == 'DECODE') { // 验证数据有效性,请看未加密明文的格式 if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) { return substr($result, 26); } else { return ''; } } else { // 把动态密匙保存在密文里,这也是为什么同样的明文,生产不同密文后能解密的原因 // 因为加密后的密文可能是一些特殊字符,复制过程可能会丢失,所以用base64编码 return $keyc . str_replace('=', '', base64_encode($result)); } } $str = 'abcdef'; $key = 'www.helloweba.com'; echo authcode($str, 'ENCODE', $key, 0); //加密 $str = '56f4yER1DI2WTzWMqsfPpS9hwyoJnFP2MpC8SOhRrxO7BOk'; echo authcode($str, 'DECODE', $key, 0); //解密 六、 /** * $string:需要加解密的字符串; * $operation:E表示加密,D表示解密; * $key:自定义密匙 */ function string($string, $operation, $key = '') { $key = md5($key); $key_length = strlen($key); $string = $operation == 'D' ? base64_decode($string) : substr(md5($string . $key), 0, 8) . $string; $string_length = strlen($string); $rndkey = $box = array(); $result = ''; for ($i = 0; $i <= 255; $i++) { $rndkey[$i] = ord($key[$i % $key_length]); $box[$i] = $i; } for ($j = $i = 0; $i < 256; $i++) { $j = ($j + $box[$i] + $rndkey[$i]) % 256; $tmp = $box[$i]; $box[$i] = $box[$j]; $box[$j] = $tmp; } for ($a = $j = $i = 0; $i < $string_length; $i++) { $a = ($a + 1) % 256; $j = ($j + $box[$a]) % 256; $tmp = $box[$a]; $box[$a] = $box[$j]; $box[$j] = $tmp; $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256])); } if ($operation == 'D') { if (substr($result, 0, 8) == substr(md5(substr($result, 8) . $key), 0, 8)) { return substr($result, 8); } else { return ''; } } else { return str_replace('=', '', base64_encode($result)); } }
-
JavaScript Cookie插件 JavaScript Cookie介绍 一个简单、轻量级的JavaScript API,用于处理Cookie 安装 <script src="https://cdn.bootcdn.net/ajax/libs/js-cookie/3.0.1/js.cookie.min.js"></script>基本用法 创建一个在整个网站上有效的cookie: Cookies.set('name', 'value')创建一个7天后过期的cookie,在整个站点上有效: Cookies.set('name', 'value', { expires: 7 })创建对当前页面路径有效的过期cookie: Cookies.set('name', 'value', { expires: 7, path: '' })读取cookie: Cookies.get('name') // => 'value' Cookies.get('nothing') // => undefined读取所有可见cookie: Cookies.get() // => { name: 'value' }*注意:通过传递一个cookie属性(可能是也可能不是)来读取特定的cookie是不可能的 在编写所述cookie时使用):* Cookies.get('foo', { domain: 'sub.example.com' }) // `domain` won't have any effect...!名为的 foo cookie将仅在以下日期提供 .get() 如果从调用代码的地方可见;读取时,域和/或路径属性不会产生影响。 删除cookie: Cookies.remove('name')删除对当前页面路径有效的cookie: Cookies.set('name', 'value', { path: '' }) Cookies.remove('name') // fail! Cookies.remove('name', { path: '' }) // removed!这很重要!删除cookie时,如果您不依赖默认属性,则必须传递与设置cookie完全相同的路径和域属性: Cookies.remove('name', { path: '', domain: '.yourdomain.com' })注意:删除不存在的cookie既不会引发任何异常,也不会返回任何值。 命名空间冲突 如果存在与名称空间 Cookies 冲突的危险,noConflict 方法将允许您定义新名称空间并保留原始名称空间。当在第三方站点上运行脚本时,这尤其有用,例如作为小部件或SDK的一部分。 // 将js cookie api分配给不同的变量,并恢复原始的“window.Cookies” var Cookies2 = Cookies.noConflict() Cookies2.set('name', 'value')注意:在 .noConflict 方法在使用AMD或CommonJS时不是必需的,因此它不会在这些环境中公开。 Cookie属性 Cookie属性默认值可以通过 withAttributes() 创建api实例来全局设置,也可以通过传递一个普通对象作为最后一个参数来单独设置对`Cookie.set(…) 的每次调用。每次调用属性覆盖默认属性。 过期 定义何时删除cookie。值必须是 Number这将被解释为从创建时算起的天数或 日期例如。如果省略,cookie将成为会话cookie。 要创建一个在一天内过期的cookie,您可以查看 Wiki上的常见问题。 默认值:当用户关闭浏览器时,将删除Cookie。 例如: Cookies.set('name', 'value', { expires: 365 }) Cookies.get('name') // => 'value' Cookies.remove('name')路径 在 String 指示cookie可见的路径。 默认值: / 例如: Cookies.set('name', 'value', { path: '' }) Cookies.get('name') // => 'value' Cookies.remove('name', { path: '' })关于Internet Explorer的说明: 由于基础WinINET InternetGetCookie实现中的一个模糊错误,IE的文档。如果设置了包含文件名的路径属性,cookie将不会返回cookie。(From Internet Explorer Cookie Internals (FAQ)) 这意味着不能使用 window.location.pathname 设置路径,如果这样的路径名包含这样的文件名: /check.html (或者至少,这样的cookie无法正确读取)。 事实上,您不应该允许不受信任的输入设置cookie属性,否则您可能会受到XSS攻击。 域名 A String 指示cookie应可见的有效域。cookie也将对所有子域可见。 默认值: Cookie仅对创建Cookie的页面的域或子域可见,Internet Explorer除外(见下文)。 示例: 假设正在 site.com 上创建cookie: Cookies.set('name', 'value', { domain: 'subdomain.site.com' }) Cookies.get('name') // => undefined (need to read at 'subdomain.site.com')关于Internet Explorer默认行为的注意事项: Q3: 如果我没有为cookie指定域属性,IE会将其发送到所有嵌套的子域吗? A: 是的,cookie上的example.com集将被发送到sub2.sub1.example.com。 Internet Explorer在这方面与其他浏览器不同。这意味着如果您省略了 domain 属性,它将在IE的子域中可见。 安全的 可以是 true 或 false ,指示cookie传输是否需要安全协议(https)。 默认值: 没有安全协议要求。 示例: Cookies.set('name', 'value', { secure: true }) Cookies.get('name') // => 'value' Cookies.remove('name')相同站点 A String, 允许控制浏览器是否随跨站点请求一起发送cookie。 默认值:未定义。 请注意,最近的浏览器将“Lax”设置为默认值,即使没有在此处指定任何内容。 示例: Cookies.set('name', 'value', { sameSite: 'strict' }) Cookies.get('name') // => 'value' Cookies.remove('name')设置默认值 const api = Cookies.withAttributes({ path: '/', domain: '.example.com' })转换器 查看 创建api的新实例,以覆盖默认解码实现。所有依赖于正确解码的get方法,如 Cookies.get() 和 Cookies.get('name') ,都将为每个cookie运行给定的转换器。返回的值将用作cookie值。 读取只能使用 escape 功能解码的其中一个cookie的示例: document.cookie = 'escaped=%u5317' document.cookie = 'default=%E5%8C%97' var cookies = Cookies.withConverter({ read: function (value, name) { if (name === 'escaped') { return unescape(value) } // 对于所有其他cookie,返回默认值 return Cookies.converter.read(value, name) } }) cookies.get('escaped') // 北 cookies.get('default') // 北 cookies.get() // { escaped: '北', default: '北' }写入 创建重写默认编码实现的api的新实例: Cookies.withConverter({ write: function (value, name) { return value.toUpperCase() } })
-
JavaScript 正则常用校验大全 手机号(mobile phone)中国(严谨), 根据工信部 2019 年最新公布的手机号段 const reg = /^(?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[189]))\d{8}$/; const str = "19119255642"; console.log(`校验 ${reg.test(str) ? "正确" : "错误"}`);Email(邮箱) const reg = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; const str = "90203918@qq.com"; console.log(`校验 ${reg.test(str) ? "正确" : "错误"}`);座机(Tel Phone)电话(国内) 如: 0341-86091234 const reg = /^(?:(?:\d{3}-)?\d{8}|^(?:\d{4}-)?\d{7,8})(?:-\d+)?$/; const str = "0936-4211235"; console.log(`校验 ${reg.test(str) ? "正确" : "错误"}`);身份证号(2 代,18 位数字),最后一位是校验位,可能为数字或字符 X const reg = /^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\d|30|31)\d{3}[\dXx]$/; const str = "12345619991205131x"; console.log(`校验 ${reg.test(str) ? "正确" : "错误"}`);中文姓名 const reg = /^(?:[\u4e00-\u9fa5·]{2,16})$/; const str = "韩小韩"; console.log(`校验 ${reg.test(str) ? "正确" : "错误"}`);英文姓名 const reg = /(^[a-zA-Z][a-zA-Z\s]{0,20}[a-zA-Z]$)/; const str = "James Han"; console.log(`校验 ${reg.test(str) ? "正确" : "错误"}`);网址(URL) const reg = /^(((ht|f)tps?):\/\/)?([^!@#$%^&*?.\s-]([^!@#$%^&*?.\s]{0,63}[^!@#$%^&*?.\s])?\.)+[a-z]{2,6}\/?/; const str = "https://www.vvhan.com"; console.log(`校验 ${reg.test(str) ? "正确" : "错误"}`);必须带端口号的网址(或 IP) const reg = /^((ht|f)tps?:\/\/)?[\w-]+(\.[\w-]+)+:\d{1,5}\/?$/; const str = "https://www.vvhan.com:80"; console.log(`校验 ${reg.test(str) ? "正确" : "错误"}`);银行卡号(10 到 30 位, 覆盖对公/私账户) const reg = /^[1-9]\d{9,29}$/; const str = "6222026006705354000"; console.log(`校验 ${reg.test(str) ? "正确" : "错误"}`);帐号是否合法(字母开头,允许 5-16 字节,允许字母数字下划线组合) const reg = /^[a-zA-Z]\w{4,15}$/; const str = "han_666666"; console.log(`校验 ${reg.test(str) ? "正确" : "错误"}`);中文/汉字 const reg = /^(?:[\u3400-\u4DB5\u4E00-\u9FEA\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0])+$/; const str = "易航博客"; console.log(`校验 ${reg.test(str) ? "正确" : "错误"}`);密码强度校验,最少 6 位,包括至少 1 个大写字母,1 个小写字母,1 个数字,1 个特殊字符 const reg = /^\S*(?=\S{6,})(?=\S*\d)(?=\S*[A-Z])(?=\S*[a-z])(?=\S*[!@#$%^&*? ])\S*$/; const str = "han@666vvx,"; console.log(`校验 ${reg.test(str) ? "正确" : "错误"}`);微信号(wx),6 至 20 位,以字母开头,字母,数字,减号,下划线 const reg = /^[a-zA-Z][-_a-zA-Z0-9]{5,19}$/; const str = "kd_-666"; console.log(`校验 ${reg.test(str) ? "正确" : "错误"}`);邮政编码(中国) const reg = /^(0[1-7]|1[0-356]|2[0-7]|3[0-6]|4[0-7]|5[1-7]|6[1-7]|7[0-5]|8[013-6])\d{4}$/; const str = "734500"; console.log(`校验 ${reg.test(str) ? "正确" : "错误"}`);中文和数字 const reg = /^((?:[\u3400-\u4DB5\u4E00-\u9FEA\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0])|(\d))+$/; const str = "易航好6啊"; console.log(`校验 ${reg.test(str) ? "正确" : "错误"}`);匹配连续重复的字符 const reg = /(.)\1+/; const str = "112233"; console.log(`校验 ${reg.test(str) ? "正确" : "错误"}`);统一社会信用代码 const reg = /^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$/; const str = "91110108772551611J"; console.log(`校验 ${reg.test(str) ? "正确" : "错误"}`);子网掩码(不包含 0.0.0.0) const reg = /^(254|252|248|240|224|192|128)\.0\.0\.0|255\.(254|252|248|240|224|192|128|0)\.0\.0|255\.255\.(254|252|248|240|224|192|128|0)\.0|255\.255\.255\.(255|254|252|248|240|224|192|128|0)$/; const str = "255.255.255.0"; console.log(`校验 ${reg.test(str) ? "正确" : "错误"}`);车牌号(新能源) const reg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z](?:((\d{5}[A-HJK])|([A-HJK][A-HJ-NP-Z0-9][0-9]{4}))|[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳])$/; const str = "京AD92035"; console.log(`校验 ${reg.test(str) ? "正确" : "错误"}`);车牌号(非新能源) const reg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z][A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]$/; const str = "京A00599"; console.log(`校验 ${reg.test(str) ? "正确" : "错误"}`);车牌号(新能源+非新能源) const reg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z][A-HJ-NP-Z0-9]{4,5}[A-HJ-NP-Z0-9挂学警港澳]$/; const str = "京A12345D"; console.log(`校验 ${reg.test(str) ? "正确" : "错误"}`);护照(包含香港、澳门) const reg = /(^[EeKkGgDdSsPpHh]\d{8}$)|(^(([Ee][a-fA-F])|([DdSsPp][Ee])|([Kk][Jj])|([Mm][Aa])|(1[45]))\d{7}$)/; const str = "s28233515"; console.log(`校验 ${reg.test(str) ? "正确" : "错误"}`);图片
-
一文搞懂HTTP和HTTPS的通信过程及区别 一、两者的区别 端口: http 端口号是80, https 端口号是443 传输协议: http 是超文本传输协议,属于明文传输;https 是安全的超-文本传输协议,是经过 SSL 加密后的传输协议 安全性: https 使用了 TLS/SSL 加密,比 http 更加的安全 证书: https 需要申请 ca 证书 二、HTTP的通信过程 理解: 作为标准的 C/S 模型, http 协议总是由客户端发起,服务端进行响应。 DNS 解析,域名系统 DNS 将域名解析成IP地址 建立 TCP 连接,进行 TCP 的三次握手 客户端发送请求 服务端响应客户端,向客户端发送数据 通信完成, TCP 连接关闭 三、HTTPS的通信过程 理解: https 通信是建立在 ssl 连接层之上的请求和响应,客户端将加密组件发送到服务端,服务端进行匹配后将数字证书等信息发送到客户端,客户端进行证书验证,验证通过后使用非对称加密对数据的密钥进行协商,协商后得到对称的加密密钥,然后使用对称算法进行 TCP 链接,然后与客户端进行三次握手后,进行数据传输,传输完成后,四次挥手,断开链接,通信结束。 客户端和服务端通过 TCP 建立连接,并发送 https 请求。 服务端响应请求,并将数字证书发送给客户端,数字证书包括 公共秘钥、域名、申请证书的公司 。 客户端收到服务端的数字证书之后,会验证数字证书的合法性。 如果公钥合格,那么客户端会生成 client key ,一个用于进行对称加密的密钥,并用服务端的公钥对客户端密钥进行非对称加密。 客户端会再次发起请求,将加密之后的客户端密钥发送给服务端。 服务端接收密文后,会用私钥对其进行非对称解密,得到客户端秘钥。并使用客户端秘钥进行对称加密,生成密文并发送。 客户端收到密文,并使用客户端秘钥进行解密,获取数据。 四、HTTPS通信过程介绍图 HTTPS通信过程介绍图图片