第一页 上页 1 2 3 4 5 6 7 8 9 10 下页 最后页 [ 显示模式: 摘要 | 列表 ]

设备像素比

[不指定 2017/01/17 10:53 | by 刘新修 ]

 /****** 以iphone为基准||宽度为100则为1倍宽 ******/

var y={}
y.fontSize=100*(document.documentElement.clientWidth/320);
var b = y.fontSize;
b = b >= 240 ? 240 : b;  //最大就240||100就是一倍宽
document.documentElement.style.fontSize = b + "px"

nginx出现502有很多原因,但大部分原因可以归结为资源数量不够用,也就是说后端php-fpm处理有问题,nginx将正确的客户端请求发给了后端的php-fpm进程,但是因为php-fpm进程的问题导致不能正确解析php代码,最终返回给了客户端502错误。

服务器出现502的原因是连接超时 我们向服务器发送请求 由于服务器当前链接太多,导致服务器方面无法给于正常的响应,产生此类报错

因此如果你服务器并发量非常大,那只能先增加机器,然后按以下方式优化会取得更好效果;但如果你并发不大却出现502,一般都可以归结为配置问题,脚本超时问题。

一、php-fpm进程数不够用

使用 netstat -napo |grep "php-fpm" | wc -l 查看一下当前fastcgi进程个数,如果个数接近conf里配置的上限,就需要调高进程数。

但也不能无休止调高,可以根据服务器内存情况,可以把php-fpm子进程数调到100或以上,在4G内存的服务器上200就可以。


二、调高调高linux内核打开文件数量

可以使用这些命令(必须是root帐号)

C#代码
  1. echo 'ulimit -HSn 65536' >> /etc/profile  
  2. echo 'ulimit -HSn 65536' >> /etc/rc.local  
  3. source /etc/profile  

三、脚本执行时间超时

 

如果脚本因为某种原因长时间等待不返回 ,导致新来的请求不能得到处理,可以适当调小如下配置。

nginx.conf里面主要是如下

C#代码
  1. fastcgi_connect_timeout 300;  
  2. fastcgi_send_timeout 300;  
  3. fastcgi_read_timeout 300;  

php-fpm.conf里如要是如下

C#代码
  1. request_terminate_timeout = 10s  

四、缓存设置比较小

 

修改或增加配置到nginx.conf

C#代码
  1. proxy_buffer_size 64k;  
  2. proxy_buffers  512k;  
  3. proxy_busy_buffers_size 128k;  

五、 recv() failed (104: Connection reset by peer) while reading response header from upstream

 

可能的原因机房网络丢包或者机房有硬件防火墙禁止访问该域名

但最重要的是程序里要设置好超时,不要使用php-fpm的request_terminate_timeout,

最好设成request_terminate_timeout=0;

因为这个参数会直接杀掉php进程,然后重启php进程,这样前端nginx就会返回104: Connection reset by peer。这个过程是很慢,总体感觉就是网站很卡。

C#代码
  1. May 01 10:50:58.044162 [WARNING] [pool www] child 4074, script '/usr/local/nginx/html/quancha/sameip/detail.php' execution timed out (15.129933 sec), terminating  
  2. May 01 10:50:58.045725 [WARNING] [pool www] child 4074 exited on signal 15 SIGTERM after 90.227060 seconds from start  
  3. May 01 10:50:58.046818 [NOTICE] [pool www] child 4082 started  

说一千道一万最重要的就是程序里控制好超时,gethostbyname、curl、file_get_contents等函数的都要设置超时时间。

 

另一个就是多说,这个东西是增加了网站的交互性,但是使用的多了反应就慢了,如果你网站超时且使用了多说是,可以关闭它。

php-fpm.conf max_children 和 max_requests配置:

pm = static

假如使用静态 pm.max_children这个参数会起作用,其余不会。动态反之。

2G内存pm.max_children大概开启50左右,按照实际情况来调优,这个是很必要的。

========================================================

max_children是PHP-FPM Pool 最大的子进程数,他数值取决于你的服务器内存。 假设你打算给10G内存给当前配置的PHP-FPM Pool,一般一个PHP请求占用内存10M-40M,我们按站点每个PHP请求占用内存25M,这样max_children = 10G/25M = 409。所以,这个值可以根据情况算出来

max_requests是每个子进程重生之前处理的请求数, 默认值为unlimited(默认为1024),可以设置小一点(如500左右),这样可以避免内存泄露带来的问题

Nginx代理过程,将业务服务器请求数据缓存到本地文件,再将文件数据转发给请求客户端。高并发的客户端请求,必然要求服务器文件句柄的并发打开限制。使用ulimit命令(ulimit -n),查看Linux系统文件句柄并发限制,默认是1024,我们可以改为65535(2 的 16 次方,这是系统端口的极限)。修改的方法为:修改系统文件/etc/security/limits.conf,添加如下信息,并重新启动系统生效。

C#代码
  1. * soft   nofile  65535  
  2.   
  3. * hard   nofile  65535  

然后在Nginx配置文件中,把文件限制及连接数信息改为65535:

C#代码
  1. worker_rlimit_nofile 65535;  
  2. events {  
  3.     use epoll;  
  4.     worker_connections  65535;  
  5. }  

 

NGINX 重写规则

[不指定 2016/11/11 12:06 | by 刘新修 ]

nginx rewrite 实现二级域名跳转

当访问http://abc.test.com跳转到http://www.test.com/test/abc/
方法一:
这种方法浏览器地址会变www.test.com/test/abc
实现访问如下:
server { 
        listen 80; 
        server_name www.test.com; 
        location / { 
                root /data/test; 
                index index.html; 
        } 
 
 
server { 
        listen 80; 
        server_name *.test.com; 
        if ( $http_host ~* "^(.*)\.test\.com$") { 
                set $domain $1; 
                rewrite ^(.*) http://www.test.com/test/$domain/ break; 
        } 
}
方法二、
 
当访问http://abc.test.com跳转到http://www.test.com/test/abc/
server {
        listen 80; 
        server_name *.test.com; 
        root /usr/local/www; 
        #这是里可以加多个目录,如果不加目录,会无法访问到abc.test.com/目录下的文件,如图片目录/images
        location ~ ^/(test|images|styles)/ 
        { 
                proxy_redirect        off; 
                proxy_set_header    Host   www.test.com; 
                proxy_pass      http://192.168.1.2:8080; 
        } 
        location / { 
                set $domain default; 
                if ( $http_host ~* "^(.*)\.test\.com$") { 
                        set $domain $1; 
                } 
                rewrite ^/(.*)    /test/$domain/$1 last; 
        } 
        access_log off;
}
 
rewrite命令
nginx的rewrite相当于apache的rewriterule(大多数情况下可以把原有apache的rewrite规则加上引号就可以直接使用),它可以用在server,location 和IF条件判断块中,命
 
令格式如下:
rewrite 正则表达式 替换目标 flag标记
flag标记可以用以下几种格式:
last - 基本上都用这个Flag。
break - 中止Rewirte,不在继续匹配
redirect - 返回临时重定向的HTTP状态302
permanent - 返回永久重定向的HTTP状态301
例如下面这段设定nginx将某个目录下面的文件重定向到另一个目录,$2对应第二个括号(.*)中对应的字符串:
 
location /download/ {
        rewrite ^(/download/.*)/m/(.*)\..*$ $1/nginx-rewrite/$2.gz break;
}
 
nginx重定向的IF条件判断
在server和location两种情况下可以使用nginx的IF条件判断,条件可以为以下几种:
正则表达式
 
如:
匹配判断
~ 为区分大小写匹配; !~为区分大小写不匹配
~* 为不区分大小写匹配;!~为不区分大小写不匹配
 
就是当用户输入 www.a.com.cn 自动跳转到www.a.com 这个域名:
 
rewrite ^/(.*)$ http://www.a.com/$1 permanent; 或者cname
例如下面设定nginx在用户使用ie的使用重定向到/nginx-ie目录下:
if ($http_user_agent ~ MSIE) {
        rewrite ^(.*)$ /nginx-ie/$1 break;
}
文件和目录判断
-f和!-f判断是否存在文件
-d和!-d判断是否存在目录
-e和!-e判断是否存在文件或目录
-x和!-x判断文件是否可执行
 
例如下面设定nginx在文件和目录不存在的时候重定向:
if (!-e $request_filename) {
        proxy_pass http://127.0.0.1;
}
 
return
返回http代码,例如设置nginx防盗链:
location ~* \.(gif|jpg|png|swf|flv)$ {
        valid_referers none blocked www.jefflei.comwww.leizhenfang.com;
        if ($invalid_referer) {
                return 404;
        }
}
 
记一正则,匹配非某单词
由于要rewrite一个地址从
/mag/xx/xxx/ -> /m/xxx
但原先 /mag/xx/more/ 要保留
这就得写一个比较奇特的正则了,尝试了比较多的写法也没成功
 
最先想的是:
 
location ~* ^/mag/[^/]+/[^(more)]+/ {
  rewrite ^/mag/[^/]+/(.*) /m/$1 permanent;
}
 
 
[]的写法并不凑效,里面是匹配单个字符的,这样无效,匹配不了
 
还是小范同学不错,研究的深入,提供了非某单词的写法 (?!more)
 
location ~* ^/mag/[^/]+/(?!more)([^/]+)/ {
  rewrite ^/mag/[^/]+/(.*) /m/$1 permanent;
}
 
 
这个写法勉强可以应付了,后面的匹配单元虽说还不完美,但也能够对付我的所有需求内容了。
有需要的可以参考此写法。
 
引用
 
常用分组语法
 
捕获
(exp) 匹配exp,并捕获文本到自动命名的组里 
(?exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成(?'name'exp) 
(?:exp) 匹配exp,不捕获匹配的文本,也不给此分组分配组号 
 
零宽断言 
(?=exp) 匹配exp前面的位置 
(?<=exp) 匹配exp后面的位置 
(?!exp) 匹配后面跟的不是exp的位置 
(?
为何要使用301重定向
在网站建设中需要网页重定向的情况很多:如网页目录结构变动,网页重命名、网页的扩展名改变、网站域名改变等。如果不做重 定向,用户的收藏和搜索引擎数据库中的旧地址只能让访客得到一个404错误信息页面,访问流量白白丧失。不仅如此,之前该页面的一切积累(比如PR值)就 都白费了。
301重定向不仅能使页面实现自动跳转,对于搜索引擎来说,也可能可以传递PR值。
nginx重定向规则详细介绍
http://www.jefflei.com/post/1015.html
rewrite命令
nginx的rewrite相当于apache的rewriterule(大多数情况下可以把原有apache的rewrite规则加上引号就可以直接使用),它可以用在server,location 和IF条件判断块中,命令格式如下:
rewrite 正则表达式 替换目标 flag标记
flag标记可以用以下几种格式:
last – 基本上都用这个Flag。
break – 中止Rewirte,不在继续匹配
redirect – 返回临时重定向的HTTP状态302
permanent – 返回永久重定向的HTTP状态301
例如下面这段设定nginx将某个目录下面的文件重定向到另一个目录,$2对应第二个括号(.*)中对应的字符串:
location /download/ {
rewrite ^(/download/.*)/m/(.*)\..*$ $1/nginx-rewrite/$2.gz break;
}
nginx重定向的IF条件判断
在server和location两种情况下可以使用nginx的IF条件判断,条件可以为以下几种:
正则表达式
如:
匹配判断
~  为区分大小写匹配; !~为区分大小写不匹配
 ~* 为不区分大小写匹配;!~为不区分大小写不匹配
例如下面设定nginx在用户使用ie的使用重定向到/nginx-ie目录下:
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /nginx-ie/$1 break;
}
文件和目录判断
  -f和!-f判断是否存在文件
 -d和!-d判断是否存在目录
 -e和!-e判断是否存在文件或目录
 -x和!-x判断文件是否可执行
例如下面设定nginx在文件和目录不存在的时候重定向:
if (!-e $request_filename) {
proxy_pass http://127.0.0.1/;
}
return
返回http代码,例如设置nginx防盗链:
location ~* \.(gif|jpg|png|swf|flv)$ {
valid_referers none blocked http://www.jefflei.com/ http://www.leizhenfang.com/;
if ($invalid_referer) {
return 404;
}
}
set
设置nginx变量
 
301重定向方法
进行了301重定向,把www .jefflei.com和jefflei.com合并,并把之前的域名也一并合并. 有两种实现方法,第一种方法是判断nginx核心变量host(老版本是http_host):
server {
server_name www.jefflei.com jefflei.com ;
if ($host != 'www.jefflei.com' ) {
rewrite ^/(.*)$ http://www.jefflei.com/$1 permanent;
}
...
}
第二种方法:
server {
server_name jefflei.com;
rewrite ^/(.*) http://www.jefflei.com/$1 permanent;
}
测试了第一种方法ok,这两种方法中, permanent是关键,详细说明见nginx重定向规则说明。
last – 基本上都用这个Flag。
break – 中止Rewirte,不在继续匹配
redirect – 返回临时重定向的HTTP状态302
permanent – 返回永久重定向的HTTP状态301
好了,现在可以检查结果,这里可以看返回的HTTP头信息:
http://www.seoconsultants.com/tools/headers.asp
第二种方法没有测试成功...
 
测试是否定向成功
http://qinfy.net/301-redirect-for-nginx/
输入指令~
/usr/local/nginx/sbin/nginx -t
提示:
the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
configuration file /usr/local/nginx/conf/nginx.conf test is successful
测试成功~ 重启nginx~ 输入指令~
/usr/local/nginx/sbin/nginx -s reload
重启之后测试一下~是否成功设定完成! 输入指令~
curl -I imcat.tk
 
会输出:
HTTP/1.1 301 Moved Permanently
Server: nginx/0.7.65
Date: Tue, 03 Aug 2010 01:12:37 GMT
Content-Type: text/html
Content-Length: 185
Connection: keep-alive
Location: http://qinfy.net/
nginx rewrite 伪静态配置参数详细说明(转)
http://hi.baidu.com/hx10/blog/item/942a0ad784f3ffd0a144df94.html
nginx rewrite 伪静态配置参数和使用例子 附正则使用说明
正则表达式匹配,其中:
* ~ 为区分大小写匹配 
* ~* 为不区分大小写匹配 
* !~和!~*分别为区分大小写不匹配及不区分大小写不匹配
 
文件及目录匹配,其中:
* -f和!-f用来判断是否存在文件 
* -d和!-d用来判断是否存在目录 
* -e和!-e用来判断是否存在文件或目录 
* -x和!-x用来判断文件是否可执行
flag标记有:
* last 相当于Apache里的[L]标记,表示完成rewrite 
* break 终止匹配, 不再匹配后面的规则 
* redirect 返回302临时重定向 地址栏会显示跳转后的地址 
* permanent 返回301永久重定向 地址栏会显示跳转后的地址
一些可用的全局变量有,可以用做条件判断(待补全)
$args 
$content_length 
$content_type 
$document_root 
$document_uri 
$host 
$http_user_agent 
$http_cookie 
$limit_rate 
$request_body_file 
$request_method 
$remote_addr 
$remote_port 
$remote_user 
$request_filename 
$request_uri 
$query_string 
$scheme 
$server_protocol 
$server_addr 
$server_name 
$server_port 
$uri
结合QeePHP的例子
if (!-d $request_filename) { 
rewrite ^/([a-z-A-Z]+)/([a-z-A-Z]+)/?(.*)$ /index.php?namespace=user&controller=$1&action=$2&$3 last; 
rewrite ^/([a-z-A-Z]+)/?$ /index.php?namespace=user&controller=$1 last; 
break;
多目录转成参数
abc.domian.com/sort/2 => abc.domian.com/index.php?act=sort&name=abc&id=2
if ($host ~* (.*)\.domain\.com) { 
set $sub_name $1; 
rewrite ^/sort\/(\d+)\/?$ /index.php?act=sort&cid=$sub_name&id=$1 last; 
}
目录对换
/123456/xxxx -> /xxxx?id=123456
rewrite ^/(\d+)/(.+)/ /$2?id=$1 last;
例如下面设定nginx在用户使用ie的使用重定向到/nginx-ie目录下:
if ($http_user_agent ~ MSIE) { 
rewrite ^(.*)$ /nginx-ie/$1 break; 
}
目录自动加“/”
if (-d $request_filename){ 
rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent; 
}
禁止htaccess
location ~/\.ht { 
deny all; 
}
禁止多个目录
location ~ ^/(cron|templates)/ { 
deny all; 
break; 
}
禁止以/data开头的文件
可以禁止/data/下多级目录下.log.txt等请求;
location ~ ^/data { 
deny all; 
}
禁止单个目录
不能禁止.log.txt能请求
location /searchword/cron/ { 
deny all; 
}
禁止单个文件
location ~ /data/sql/data.sql { 
deny all; 
}
给favicon.ico和robots.txt设置过期时间;
这里为favicon.ico为99 天,robots.txt为7天并不记录404错误日志
location ~(favicon.ico) { 
log_not_found off; 
expires 99d; 
break; 
 
location ~(robots.txt) { 
log_not_found off; 
expires 7d; 
break; 
}
设定某个文件的过期时间;这里为600秒,并不记录访问日志
location ^~ /html/scripts/loadhead_1.js { 
access_log off; 
root /opt/lampp/htdocs/web; 
expires 600; 
break; 
}
文件反盗链并设置过期时间
这里的return 412 为自定义的http状态码,默认为403,方便找出正确的盗链的请求
“rewrite ^/ http://leech.c1gstudio.com/leech.gif;”显示一张防盗链图片
“access_log off;”不记录访问日志,减轻压力
“expires 3d”所有文件3天的浏览器缓存
location ~* ^.+\.(jpg|jpeg|gif|png|swf|rar|zip|css|js)$ { 
valid_referers none blocked *.c1gstudio.com *.c1gstudio.net localhost 208.97.167.194; 
if ($invalid_referer) { 
rewrite ^/ http://leech.c1gstudio.com/leech.gif; 
return 412; 
break; 
access_log off; 
root /opt/lampp/htdocs/web; 
expires 3d; 
break; 
}
只充许固定ip访问网站,并加上密码
root /opt/htdocs/www; 
allow 208.97.167.194; 
allow 222.33.1.2; 
allow 231.152.49.4; 
deny all; 
auth_basic "C1G_ADMIN"; 
auth_basic_user_file htpasswd;
将多级目录下的文件转成一个文件,增强seo效果
/job-123-456-789.html 指向/job/123/456/789.html
rewrite ^/job-([0-9]+)-([0-9]+)-([0-9]+)\.html$ /job/$1/$2/jobshow_$3.html last;
将根目录下某个文件夹指向2级目录
如/shanghaijob/ 指向 /area/shanghai/
如果你将last改成permanent,那么浏览器地址栏显是 /location/shanghai/
rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2 last;
上面例子有个问题是访问/shanghai 时将不会匹配
rewrite ^/([0-9a-z]+)job$ /area/$1/ last; 
rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2 last;
这样/shanghai 也可以访问了,但页面中的相对链接无法使用,
如./list_1.html真实地址是/area /shanghia/list_1.html会变成/list_1.html,导至无法访问。
那我加上自动跳转也是不行咯
(-d $request_filename)它有个条件是必需为真实目录,而我的rewrite不是的,所以没有效果
if (-d $request_filename){ 
rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent; 
}
知道原因后就好办了,让我手动跳转吧
rewrite ^/([0-9a-z]+)job$ /$1job/ permanent; 
rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2 last;
文件和目录不存在的时候重定向:
if (!-e $request_filename) { 
proxy_pass http://127.0.0.1/; 
}
域名跳转
server 
listen 80; 
server_name jump.c1gstudio.com; 
index index.html index.htm index.php; 
root /opt/lampp/htdocs/www; 
rewrite ^/ http://www.c1gstudio.com/; 
access_log off; 
}
多域名转向
server_name http://www.c1gstudio.com/ http://www.c1gstudio.net/; 
index index.html index.htm index.php; 
root /opt/lampp/htdocs; 
if ($host ~ "c1gstudio\.net") { 
rewrite ^(.*) http://www.c1gstudio.com$1/ permanent; 
}
三级域名跳转
if ($http_host ~* "^(.*)\.i\.c1gstudio\.com$") { 
rewrite ^(.*) http://top.yingjiesheng.com$1/; 
break; 
}
域名镜向
server 
listen 80; 
server_name mirror.c1gstudio.com; 
index index.html index.htm index.php; 
root /opt/lampp/htdocs/www; 
rewrite ^/(.*) http://www.c1gstudio.com/$1 last; 
access_log off; 
}
某个子目录作镜向
location ^~ /zhaopinhui { 
rewrite ^.+ http://zph.c1gstudio.com/ last; 
break; 
}
discuz ucenter home (uchome) rewrite
rewrite ^/(space|network)-(.+)\.html$ /$1.php?rewrite=$2 last; 
rewrite ^/(space|network)\.html$ /$1.php last; 
rewrite ^/([0-9]+)$ /space.php?uid=$1 last;
discuz 7 rewrite
rewrite ^(.*)/archiver/((fid|tid)-[\w\-]+\.html)$ $1/archiver/index.php?$2 last; 
rewrite ^(.*)/forum-([0-9]+)-([0-9]+)\.html$ $1/forumdisplay.php?fid=$2&page=$3 last; 
rewrite ^(.*)/thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ $1/viewthread.php?tid=$2&extra=page\%3D$4&page=$3 last; 
rewrite ^(.*)/profile-(username|uid)-(.+)\.html$ $1/viewpro.php?$2=$3 last; 
rewrite ^(.*)/space-(username|uid)-(.+)\.html$ $1/space.php?$2=$3 last; 
rewrite ^(.*)/tag-(.+)\.html$ $1/tag.php?name=$2 last;
给discuz某版块单独配置域名
server_name bbs.c1gstudio.com news.c1gstudio.com; 
 
location = / { 
if ($http_host ~ news\.c1gstudio.com$) { 
rewrite ^.+ http://news.c1gstudio.com/forum-831-1.html last; 
break; 
}
discuz ucenter 头像 rewrite 优化
location ^~ /ucenter { 
location ~ .*\.php?$ 
#fastcgi_pass unix:/tmp/php-cgi.sock; 
fastcgi_pass 127.0.0.1:9000; 
fastcgi_index index.php; 
include fcgi.conf; 
 
location /ucenter/data/avatar { 
log_not_found off; 
access_log off; 
location ~ /(.*)_big\.jpg$ { 
error_page 404 /ucenter/images/noavatar_big.gif; 
location ~ /(.*)_middle\.jpg$ { 
error_page 404 /ucenter/images/noavatar_middle.gif; 
location ~ /(.*)_small\.jpg$ { 
error_page 404 /ucenter/images/noavatar_small.gif; 
expires 300; 
break; 
}
jspace rewrite
location ~ .*\.php?$ 
#fastcgi_pass unix:/tmp/php-cgi.sock; 
fastcgi_pass 127.0.0.1:9000; 
fastcgi_index index.php; 
include fcgi.conf; 
 
location ~* ^/index.php/ 
rewrite ^/index.php/(.*) /index.php?$1 break; 
fastcgi_pass 127.0.0.1:9000; 
fastcgi_index index.php; 
include fcgi.conf; 
}
Tags: ,

有时我们想截取最后一个斜杠'/'后面的数字;

有时我们又需要截取第一个斜杠'/'前面的内容判断用户输入的url链接带不带http://等等;

字符串的截取php内置函数就有很多种;简单的写几个示例;

1
$str='123/456/789/abc';

截取第一个斜杠前面的内容可以这样来:

1
echo substr($str,0,strpos($str'/'))

    或者

1
2
3
$array=explode('/'$str);
echo $array[0];
// 输出 123

截取第一个斜杠后面的内容可以这样来:

1
2
echo substr($str,strpos($str,'/')+1);
//输出 456/789/abc

 

截取最后一个斜杠后面的内容可以这样来:

1
echo trim(strrchr($str'/'),'/');

    或者如果知道斜杠的个数

1
2
3
$array=explode('/'$str);
echo $array[3];
//输出 abc

 

但是问题来了;如果不知道有多少个斜杠呢?如果想要第二个斜杠和第三个斜杠中间的内容呢?

下面我写的这个函数就可以轻松解决如上 所有问题;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
 * 按符号截取字符串的指定部分
 * @param string $str 需要截取的字符串
 * @param string $sign 需要截取的符号
 * @param int $number 如是正数以0为起点从左向右截  负数则从右向左截
 * @return string 返回截取的内容
 */
 
function cut_str($str,$sign,$number){
    $array=explode($sign$str);
    $length=count($array);
    if($number<0){
        $new_array=array_reverse($array);
        $abs_number=abs($number);
        if($abs_number>$length){
            return 'error';
        }else{
            return $new_array[$abs_number-1];
        }
    }else{
        if($number>=$length){
            return 'error';
        }else{
            return $array[$number];
        }
    }
}

示例:

1
2
3
4
echo cut_str($str,'/',0); //输出 123
echo cut_str($str,'/',2); //输出 789
echo cut_str($str,'/',-1);//输出 abc
echo cut_str($str,'/',-3);//输出 456
Tags: ,

js判断滚动条滚动方向

[不指定 2016/10/25 10:09 | by 刘新修 ]
JavaScript代码
  1. //第一种写法  
  2.         var a;  
  3.             
  4.         function scroll( fn ) {  
  5.             var beforeScrollTop = document.body.scrollTop,  
  6.                 fn = fn || function() {};  
  7.             window.addEventListener("scroll", function() {  
  8.                 var afterScrollTop = document.body.scrollTop,  
  9.                     delta = afterScrollTop - beforeScrollTop;  
  10.                 if( delta === 0 ) return false;  
  11.                 fn( delta > 0 ? "down" : "up" );  
  12.                 beforeScrollTop = afterScrollTop;  
  13.             }, false);  
  14.         }  
  15.         scroll(function(direction) {  
  16.             // console.log(direction);  
  17.             a =  direction;  
  18.         });  
  19.         // 第二种写法  
  20.         var a;  
  21.             
  22.         function scroll( fn ) {  
  23.             var beforeScrollTop = document.body.scrollTop,  
  24.                 fn = fn || function() {};  
  25.             window.addEventListener("scroll", function() {  
  26.                 var afterScrollTop = document.body.scrollTop,  
  27.                     delta = afterScrollTop - beforeScrollTop;  
  28.                 if( delta === 0 ) return false;  
  29.                 a = fn( delta > 0 ? "down" : "up" );  
  30.                 beforeScrollTop = afterScrollTop;  
  31.             }, false);  
  32.         }  
  33.         scroll(function(direction) {  
  34.             // console.log(direction);  
  35.             return direction;  
  36.         });  
  37.         // 第三种写法-----=是执行完事件后的回调函数  
  38.   
  39.         var a;  
  40.         var beforeScrollTop = document.body.scrollTop,  
  41.             fn = fn || function() {};  
  42.         window.addEventListener("scroll", function() {  
  43.             var afterScrollTop = document.body.scrollTop,  
  44.                 delta = afterScrollTop - beforeScrollTop;  
  45.             if( delta === 0 ) return false;  
  46.             fn( delta > 0 ? "down" : "up" );  
  47.             beforeScrollTop = afterScrollTop;  
  48.         }, false);  
  49.         function fn(direction) {  
  50.             // console.log(direction);  
  51.             a = direction;  
  52.         };  
  53.   
  54.         window.onscroll=function(){  
  55.             console.log(a);  
  56.         }  
Tags: ,

component的生命周期图

getDefaultProps

object getDefaultProps()

执行过一次后,被创建的类会有缓存,映射的值会存在this.props,前提是这个prop不是父组件指定的 
这个方法在对象被创建之前执行,因此不能在方法内调用this.props ,另外,注意任何getDefaultProps()返回的对象在实例中共享,不是复制

getInitialState

object getInitialState()

控件加载之前执行,返回值会被用于state的初始化值

componentWillMount

void componentWillMount()

执行一次,在初始化render之前执行,如果在这个方法内调用setStaterender()知道state发生变化,并且只执行一次

render

ReactElement render()

render的时候会调用render()会被调用 
调用render()方法时,首先检查this.propsthis.state返回一个子元素,子元素可以是DOM组件或者其他自定义复合控件的虚拟实现 
如果不想渲染可以返回null或者false,这种场景下,React渲染一个<noscript>标签,当返回null或者false时,ReactDOM.findDOMNode(this)返回null 
render()方法是很纯净的,这就意味着不要在这个方法里初始化组件的state,每次执行时返回相同的值,不会读写DOM或者与服务器交互,如果必须如服务器交互,在componentDidMount()方法中实现或者其他生命周期的方法中实现,保持render()方法纯净使得服务器更准确,组件更简单

componentDidMount

void componentDidMount()

在初始化render之后只执行一次,在这个方法内,可以访问任何组件,componentDidMount()方法中的子组件在父组件之前执行

从这个函数开始,就可以和 JS 其他框架交互了,例如设置计时 setTimeout 或者 setInterval,或者发起网络请求

shouldComponentUpdate

boolean shouldComponentUpdate(   object nextProps, object nextState )
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

这个方法在初始化render时不会执行,当props或者state发生变化时执行,并且是在render之前,当新的props或者state不需要更新组件时,返回false

shouldComponentUpdate: function(nextProps, nextState) {   return nextProps.id !== this.props.id; }
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

shouldComponentUpdate方法返回false时,讲不会执行render()方法,componentWillUpdatecomponentDidUpdate方法也不会被调用

默认情况下,shouldComponentUpdate方法返回true防止state快速变化时的问题,但是如果·state不变,props只读,可以直接覆盖shouldComponentUpdate用于比较propsstate的变化,决定UI是否更新,当组件比较多时,使用这个方法能有效提高应用性能

componentWillUpdate

void componentWillUpdate(   object nextProps, object nextState )
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

propsstate发生变化时执行,并且在render方法之前执行,当然初始化render时不执行该方法,需要特别注意的是,在这个函数里面,你就不能使用this.setState来修改状态。这个函数调用之后,就会把nextPropsnextState分别设置到this.propsthis.state中。紧接着这个函数,就会调用render()来更新界面了

componentDidUpdate

void componentDidUpdate(   object prevProps, object prevState )
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

组件更新结束之后执行,在初始化render时不执行

componentWillReceiveProps

void componentWillReceiveProps(   object nextProps )
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

props发生变化时执行,初始化render时不执行,在这个回调函数里面,你可以根据属性的变化,通过调用this.setState()来更新你的组件状态,旧的属性还是可以通过this.props来获取,这里调用更新状态是安全的,并不会触发额外的render调用

componentWillReceiveProps: function(nextProps) {   this.setState({     likesIncreasing: nextProps.likeCount > this.props.likeCount   }); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

componentWillUnmount

void componentWillUnmount()

当组件要被从界面上移除的时候,就会调用componentWillUnmount(),在这个函数中,可以做一些组件相关的清理工作,例如取消计时器、网络请求等

总结

React Native的生命周期就介绍完了,其中最上面的虚线框和右下角的虚线框的方法一定会执行,左下角的方法根据props state是否变化去执行,其中建议只有在componentWillMount,componentDidMount,componentWillReceiveProps方法中可以修改state

英文地址:https://facebook.github.io/react/docs/component-specs.html#lifecycle-methods

组件的生命周期

组件的生命周期分成三个状态:

  • Mounting:已插入真实 DOM

  • Updating:正在被重新渲染

  • Unmounting:已移出真实 DOM

React 为每个状态都提供了两种处理函数,will 函数在进入状态之前调用,did 函数在进入状态之后调用,三种状态共计五种处理函数。

  • componentWillMount()

  • componentDidMount()

  • componentWillUpdate(object nextProps, object nextState)

  • componentDidUpdate(object prevProps, object prevState)

  • componentWillUnmount()

此外,React 还提供两种特殊状态的处理函数。

  • componentWillReceiveProps(object nextProps):已加载组件收到新的参数时调用

  • shouldComponentUpdate(object nextProps, object nextState):组件判断是否重新渲染时调用

Tags: ,

本站测试实例访问地址: http://code.liuxinxiu.com/php/Interface/html/WebSocket.html

XML/HTML代码
  1. <!DOCTYPE html>  
  2. <html>  
  3.     <head>  
  4.         <title>chatdemo</title>  
  5.         <meta charset="utf-8">  
  6.         <meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, user-scalable=no">  
  7.         <link href="http://code.liuxinxiu.com/lib/bootstrap/3.3.2/bootstrap.min.css" rel="stylesheet">  
  8.         <style type="text/css">  
  9.         <!--  
  10.         html, body {  
  11.           min-height: 100%; }  
  12.   
  13.         body {  
  14.           margin: 0;  
  15.           padding: 0;  
  16.           width: 100%;  
  17.           font-family: "Microsoft Yahei",sans-serif, Arial; }  
  18.   
  19.         .container {  
  20.           text-align: center; }  
  21.   
  22.         .title {  
  23.           font-size: 16px;  
  24.           color: rgba(0, 0, 0, 0.3);  
  25.           position: fixed;  
  26.           z-index:1000;  
  27.           line-height: 30px;  
  28.           height: 30px;  
  29.           left: 0px;  
  30.           right: 0px;  
  31.           background-color: white; }  
  32.   
  33.         .content {  
  34.           background-color: #f1f1f1;  
  35.           border-top-left-radius: 6px;  
  36.           border-top-right-radius: 6px;  
  37.           margin-top: 30px; }  
  38.           .content .show-area {  
  39.             text-align: left;  
  40.             padding-top: 8px;  
  41.             padding-bottom: 168px; }  
  42.             .content .show-area .message {  
  43.               width: 70%;  
  44.               padding: 5px;  
  45.               word-wrap: break-word;  
  46.               word-break: normal; }  
  47.           .content .write-area {  
  48.             position: fixed;  
  49.             bottom: 0px;  
  50.             right: 0px;  
  51.             left: 0px;  
  52.             background-color: #f1f1f1;  
  53.             z-index: 10;  
  54.             width: 100%;  
  55.             height: 160px;  
  56.             border-top: 1px solid #d8d8d8; }  
  57.             .content .write-area .send {  
  58.               position: relative;  
  59.               top: -28px;  
  60.               height: 28px;  
  61.               border-top-left-radius: 55px;  
  62.               border-top-right-radius: 55px; }  
  63.             .content .write-area #name{  
  64.               position: relative;  
  65.               top: -20px;  
  66.               line-height: 28px;  
  67.               font-size: 13px; }  
  68.         -->  
  69.         </style>  
  70.     </head>  
  71.     <body>  
  72.         <div class="container">  
  73.             <div class="title">简易聊天demo</div>  
  74.             <div class="content">  
  75.                 <div class="show-area"></div>  
  76.                 <div class="write-area">  
  77.                     <div><button class="btn btn-default send" >发送</button></div>  
  78.                     <div><input name="name" id="name" type="text" placeholder="input your name"></div>  
  79.                     <div>  
  80.                         <textarea name="message" id="message" cols="38" rows="4" placeholder="input your message..."></textarea>  
  81.                     </div>                      
  82.                 </div>  
  83.             </div>  
  84.         </div>  
  85.   
  86.         <script src="http://code.liuxinxiu.com/lib/jquery/1.9.1/jquery.min.js"></script>  
  87.         <script src="http://code.liuxinxiu.com/lib/bootstrap/3.3.2/bootstrap.min.js"></script>  
  88.         <script>  
  89.         $(function(){  
  90.         var wsurl='ws://code.liuxinxiu.com:9090/php/webSocket/server.php';  
  91.             var websocket;  
  92.             var i = 0;  
  93.             /******** 判断是否有webSocket对象 *******/  
  94.             if(window.WebSocket){  
  95.                 websocket=new WebSocket(wsurl);  
  96.   
  97.                 /******** 连接建立||发起webSocket连接 ********/  
  98.                 websocket.onopen = function(evevt){  
  99.                     console.log("Connected to WebSocket server.");  
  100.                     /******** 监听ready状态码 ********/  
  101.                     console.log('websocket.readyState:'+websocket.readyState);  
  102.                     /*********************************************************  
  103.                       值为0值表示该连接尚未建立  
  104.                       值为1表示连接建立和沟通是可能的  
  105.                       值为2表示连接是通过将结束握手  
  106.                       值为3表示连接已关闭或无法打开  
  107.                     *********************************************************/  
  108.                     /******** 判断状态码为1则连接成功即可正常通信********/  
  109.                     if(websocket.readyState==1){  
  110.                         $('.show-area').append('<p class="bg-info message"><i class="glyphicon glyphicon-info-sign"></i>Connected to WebSocket server!</p>');  
  111.                     }  
  112.                 }  
  113.                 //收到消息  
  114.                 websocket.onmessage = function(event) {  
  115.                     var msg = JSON.parse(event.data); //解析收到的json消息数据  
  116.                     console.log("\n--->>message:\n"+event.data);  
  117.   
  118.                     var type = msg.type; // 消息类型  
  119.                     var umsg = msg.message; //消息文本  
  120.                     var uname = msg.name; //发送人  
  121.                     i++;  
  122.                     if(type == 'usermsg'){  
  123.                         $('.show-area').append('<p class="bg-success message"><i class="glyphicon glyphicon-user"></i><a name="'+i+'"></a><span class="label label-primary">'+uname+' say: </span>'+umsg+'</p>');  
  124.                     }  
  125.                     if(type == 'system'){  
  126.                         $('.show-area').append('<p class="bg-warning message"><a name="'+i+'"></a><i class="glyphicon glyphicon-info-sign"></i>'+umsg+'</p>');  
  127.                     }  
  128.                       
  129.                     $('#message').val('');  
  130.                     window.location.hash = '#'+i;  
  131.                 }  
  132.   
  133.                 //发生错误  
  134.                 websocket.onerror = function(event){  
  135.                     i++;  
  136.                     console.log("Connected to WebSocket server error");  
  137.                     $('.show-area').append('<p class="bg-danger message"><a name="'+i+'"></a><i class="glyphicon glyphicon-info-sign"></i>Connect to WebSocket server error.</p>');  
  138.                     window.location.hash = '#'+i;  
  139.                 }  
  140.   
  141.                 //连接关闭  
  142.                 websocket.onclose = function(event){  
  143.                     i++;  
  144.                     console.log('websocket Connection Closed. ');  
  145.                     $('.show-area').append('<p class="bg-warning message"><a name="'+i+'"></a><i class="glyphicon glyphicon-info-sign"></i>websocket Connection Closed.</p>');  
  146.                     window.location.hash = '#'+i;  
  147.                 }  
  148.   
  149.                 function send(){  
  150.                     var name = $('#name').val();  
  151.                     var message = $('#message').val();  
  152.                     if(!name){  
  153.                         alert('请输入用户名!');  
  154.                         return false;  
  155.                     }  
  156.                     if(!message){  
  157.                         alert('发送消息不能为空!');  
  158.                         return false;  
  159.                     }  
  160.                     var msg = {  
  161.                         message: message,  
  162.                         name: name  
  163.                     };  
  164.                     try{    
  165.                         websocket.send(JSON.stringify(msg));  
  166.                     } catch(ex) {    
  167.                         console.log(ex);  
  168.                     }    
  169.                 }  
  170.   
  171.                 //按下enter键发送消息  
  172.                 $(window).keydown(function(event){  
  173.                     if(event.keyCode == 13){  
  174.                         console.log('user enter');  
  175.                         send();  
  176.                     }  
  177.                 });  
  178.   
  179.                 //点发送按钮发送消息  
  180.                 $('.send').bind('click',function(){  
  181.                     send();  
  182.                 });  
  183.                   
  184.             }  
  185.             else{  
  186.                 alert('该浏览器不支持web socket');  
  187.             }  
  188.   
  189.         });      
  190.         </script>          
  191.     </body>  
  192. </html>  

后端PHP代码部分:

PHP代码
  1. 2.php code:  
  2. <?php  
  3. $host = '127.0.0.1';  
  4. $port = '9090';  
  5. $null = NULL;  
  6.   
  7. //创建tcp socket  
  8. $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);  
  9. socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);  
  10. socket_bind($socket, 0, $port);  
  11.   
  12. //监听端口  
  13. socket_listen($socket);  
  14.   
  15. //连接的client socket 列表  
  16. $clients = array($socket);  
  17.   
  18. //设置一个死循环,用来监听连接 ,状态  
  19. while (true) {  
  20.       
  21.     $changed = $clients;  
  22.     socket_select($changed, $null, $null, 0, 10);  
  23.       
  24.     //如果有新的连接  
  25.     if (in_array($socket, $changed)) {  
  26.         //接受并加入新的socket连接  
  27.         $socket_new = socket_accept($socket);  
  28.         $clients[] = $socket_new;  
  29.           
  30.         //通过socket获取数据执行handshake  
  31.         $header = socket_read($socket_new, 1024);  
  32.         perform_handshaking($header, $socket_new, $host, $port);  
  33.           
  34.         //获取client ip 编码json数据,并发送通知  
  35.         socket_getpeername($socket_new, $ip);  
  36.         $response = mask(json_encode(array('type'=>'system', 'message'=>$ip.' connected')));  
  37.         send_message($response);  
  38.         $found_socket = array_search($socket, $changed);  
  39.         unset($changed[$found_socket]);  
  40.     }  
  41.       
  42.     //轮询 每个client socket 连接  
  43.     foreach ($changed as $changed_socket) {      
  44.           
  45.         //如果有client数据发送过来  
  46.         while(socket_recv($changed_socket, $buf, 1024, 0) >= 1)  
  47.         {  
  48.             //解码发送过来的数据  
  49.             $received_text = unmask($buf);  
  50.             $tst_msg = json_decode($received_text);    
  51.             $user_name = $tst_msg->name;  
  52.             $user_message = $tst_msg->message;  
  53.               
  54.             //把消息发送回所有连接的 client 上去  
  55.             $response_text = mask(json_encode(array('type'=>'usermsg', 'name'=>$user_name, 'message'=>$user_message)));  
  56.             send_message($response_text);  
  57.             break 2;  
  58.         }  
  59.           
  60.         //检查offline的client  
  61.         $buf = @socket_read($changed_socket, 1024, PHP_NORMAL_READ);  
  62.         if ($buf === false) {  
  63.             $found_socket = array_search($changed_socket, $clients);  
  64.             socket_getpeername($changed_socket, $ip);  
  65.             unset($clients[$found_socket]);  
  66.             $response = mask(json_encode(array('type'=>'system', 'message'=>$ip.' disconnected')));  
  67.             send_message($response);  
  68.         }  
  69.     }  
  70. }  
  71. // 关闭监听的socket  
  72. socket_close($sock);  
  73.   
  74. //发送消息的方法  
  75. function send_message($msg)  
  76. {  
  77.     global $clients;  
  78.     foreach($clients as $changed_socket)  
  79.     {  
  80.         @socket_write($changed_socket,$msg,strlen($msg));  
  81.     }  
  82.     return true;  
  83. }  
  84.   
  85.   
  86. //解码数据  
  87. function unmask($text) {  
  88.     $length = ord($text[1]) & 127;  
  89.     if($length == 126) {  
  90.         $masks = substr($text, 4, 4);  
  91.         $data = substr($text, 8);  
  92.     }  
  93.     elseif($length == 127) {  
  94.         $masks = substr($text, 10, 4);  
  95.         $data = substr($text, 14);  
  96.     }  
  97.     else {  
  98.         $masks = substr($text, 2, 4);  
  99.         $data = substr($text, 6);  
  100.     }  
  101.     $text = "";  
  102.     for ($i = 0; $i < strlen($data); ++$i) {  
  103.         $text .= $data[$i] ^ $masks[$i%4];  
  104.     }  
  105.     return $text;  
  106. }  
  107.   
  108. //编码数据  
  109. function mask($text)  
  110. {  
  111.     $b1 = 0x80 | (0x1 & 0x0f);  
  112.     $length = strlen($text);  
  113.       
  114.     if($length <= 125)  
  115.         $header = pack('CC', $b1, $length);  
  116.     elseif($length > 125 && $length < 65536)  
  117.         $header = pack('CCn', $b1, 126, $length);  
  118.     elseif($length >= 65536)  
  119.         $header = pack('CCNN', $b1, 127, $length);  
  120.     return $header.$text;  
  121. }  
  122.   
  123. //握手的逻辑  
  124. function perform_handshaking($receved_header,$client_conn, $host, $port)  
  125. {  
  126.     $headers = array();  
  127.     $lines = preg_split("/\r\n/", $receved_header);  
  128.     foreach($lines as $line)  
  129.     {  
  130.         $line = chop($line);  
  131.         if(preg_match('/\A(\S+): (.*)\z/', $line, $matches))  
  132.         {  
  133.             $headers[$matches[1]] = $matches[2];  
  134.         }  
  135.     }  
  136.   
  137.     $secKey = $headers['Sec-WebSocket-Key'];  
  138.     $secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));  
  139.     $upgrade  = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .  
  140.     "Upgrade: websocket\r\n" .  
  141.     "Connection: Upgrade\r\n" .  
  142.     "WebSocket-Origin: $host\r\n" .  
  143.     "WebSocket-Location: ws://$host:$port/demo/shout.php\r\n".  
  144.     "Sec-WebSocket-Accept:$secAccept\r\n\r\n";  
  145.     socket_write($client_conn,$upgrade,strlen($upgrade));  
  146. }  
Tags: ,

关于Javascript的this

[不指定 2016/09/27 16:54 | by 刘新修 ]
this是Javascript语言的一个关键字,它是一个指针,根据不同情形下指向不同的对象,随着函数使用场合的不同,this的值会发生变化。
 
记住一条:当function被作为method调用时,this指向调用对象。另外,JavaScript并不是OO的,而是object based的一种语言。之所以你会觉得this用起来混乱,是因为你还没理解JavaScript的诸如全局对象、event handler等一些机制。
 
this指向变化通常有以下几种情形:
 
情况一:纯粹的函数调用[作为method调用]
 
JavaScript代码
  1. function test(){  
  2.   this.x = 1;  
  3.   alert(this.x);  
  4. }  
  5. test(); // 1  
以上function属于全局性调用,因此this就代表全局对象Global,为了证明它指向window 我们在window下给设置一个变量并去掉内部的赋值:
 
JavaScript代码
  1. var x = 1;  
  2. function test(){  
  3.   alert(this.x); //取window下的x  
  4. }  
  5. test(); // 1  
  6.   
  7.   
  8. var x = 1;  
  9. function test(){  
  10.   this.x = 0; //this指针依然是window,只是重新复制而已  
  11. }  
  12. test();  
  13. alert(x); //0  
情况二:作为对象方法的调用
 
作为对象的方法调用时,这时this指针就指这个对象,而不是window!
 
JavaScript代码
  1. function test(){  
  2.  alert(this.x);  
  3. }  
  4. var o = {};  
  5. o.x = 1;  
  6. o.m = test;  
  7. o.m(); // 1  
为了验证以下此时this能不能指向window我们做如下改动:
 
JavaScript代码
  1. var x='windowX';  
  2. function test(){  
  3.  alert(this.x);  
  4. }  
  5. var o = {};  
  6. //o.x = 1;  
  7. o.m = test;  
  8. o.m(); // undefined  -->可见this不可能指向window  
情况三 作为构造函数调用
 
所谓构造函数,就是通过这个函数生成一个新对象(object)。这时,this就指这个新对象。
 
JavaScript代码
  1. function test(){  
  2.   this.x = 1;  
  3. }  
  4. var o = new test();  
  5. alert(o.x); // 1  
同样,为了验证以下此时this能不能指向window我们做如下改动:
 
JavaScript代码
  1. var x='windowX';  
  2. function test(){  
  3.    this.x = 1;  
  4. }  
  5. var o = new test();  
  6. alert(o.x); // 1   -->可见this不可能指向window  
  7. alert(x); // windowX  
情况四 apply调用
 
apply()是函数体的一个方法,它的作用是改变函数的调用对象,它的第一个参数就表示改变后的调用这个函数的对象。因此,this指的就是这第一个参数
 
JavaScript代码
  1. var x = 'windowX';  
  2. function test(){  
  3.   alert(this.x);  
  4. }  
  5. var o={};  
  6. o.x = 1;  
  7. o.m = test;  
  8. o.m.apply(); //windowX m函数的apply更改了调用对象-->window  
apply()的参数为空时,默认调用全局对象。因此,这时的运行结果为windowX,证明this指的是全局window对象。
 
如果把最后一行代码修改为:
 
JavaScript代码
  1. o.m.apply(o); //1 运行结果就变成了1,证明this又指向了默认的o对象  
练习测试题:
 
JavaScript代码
  1. /******** this指针及变量提升的问题 ********/  
  2. var foo='windowFoo';  
  3. function main(){  
  4.     alert(foo);               //第一个alert,一般规则是先查找当前内部变量有没有,有则取没有找上一层     
  5.     var foo = 2;  
  6.     alert(this.foo);          //第二个alert,  
  7.     this.foo = 3;}  
注明:首先说下window下直接调用main()方法 this==window
 
测试1: var m1=main(); //作为普通函数调用或者直接调用main()
 
第一个alert属于特殊情况,内部有同名变量存在且在后边定义,涉及到了变量提升,因此输出:undefined
 
第二个alert属于查找this指针对象下的属性,this指针指向window固输出:windowFoo 而不是后边的3
 
 
测试1: var m2=new main();  //作为构造函数实例化之后调用
 
第一个alert 输出undefined因为构造函数实例化后this指向该对象,不会变化
 
第二个alert 输出undefined因为this.foo被实例化对象继承后等同于增加一个属性方法,且在alert之后,因此输出:undefined
Tags: ,
第一部分[原型prototype]:
 
任何对象及Function方法都有所对应的"prototype"原型!一切基于原型!
 
任何类型对象都有所对应的"constructor"构造器即内置构造函数,任何自定义函数及内置函数都有所对应的原型对象,说到底大家都会继承有: "对象/Object"的原型。
 
注:那怕是用字面量声明的对象var str='ss'; 其构造器使用了function String(){} 则间接使用了String.prototype的原型!
 
str 是用String()函数构造的实例!也就是说String函数的prototype原型就是str实例的间接原型!
 
JavaScript代码
  1. /******** 自定义构造函数 ********/  
  2. function Fun(){}  
  3. var foo=new Fun();  
  4. foo.constructor==Fun()  
  5. //也就是说自定义Fun函数的prototype原型就是foo实例的间接原型!自定义function的原型将继承Object  
  6.   
  7. /******** 实例对象可以直接使用__proto__找到构造器使用的prototype ********/  
  8. foo.__proto__==foo.construtor.prototype;  
  9. //true, 但是,__proto__属性在IE浏览器中一直到IE11才被支持  
  10.   
  11.   
  12. /******** 自定义函数和原型的关系 ********/  
  13. function c(){}  
  14. c.prototype  
  15. ->c {}  
  16. --->constructor: function()  
  17. --->proto: Object  //对象继承的原型  
  18. ============================================================================  
  19. c.constructor      //c本身已经是构造器了  
  20. function Function() { [native code] }  
  21. Function.prototype //构造函数Function的原型,如果没有特殊定义就是空function  
  22. function (){}  
  23. ============================================================================  
  24.   
  25. /******** 布尔值实例 ********/  
  26. true.constructor  
  27. function Boolean(){ [native code] }  
  28. Boolean.prototype  
  29. -> Boolean{ [[PrimitiveValue]]: false}  
  30. --->constructor: function Boolean()  
  31. --->toString: function toString()  
  32. --->valueOf: function valueOf()  
  33. ---> proto : Object   //对象继承的原型  
JavaScript代码
  1. var arr=[    
  2. {    
  3.     "picSrc""http://code.liuxinxiu.com/upload/user/1460273594384A3577E4_c.jpg",    
  4.     "name""贤惠的含羞草",    
  5.     "age""36岁",    
  6.     "stature""164cm",    
  7.     "character""顾家",    
  8.     "info""寻找北京的男生",    
  9.     "distance""3.0km"    
  10. },    
  11. {    
  12.     "picSrc""http://code.liuxinxiu.com/upload/user/1470127527444A8EF6B2_c.png",    
  13.     "name""微微笑",    
  14.     "age""28岁",    
  15.     "stature""164cm",    
  16.     "character""可爱",    
  17.     "info""寻找北京 28~40岁的男生",    
  18.     "distance""1.2km"    
  19. }    
  20. ];    
  21. /******** 循环取得获取图片名称 ********/    
  22. for(i in arr){    
  23.     if(arr[i].picSrc){    
  24.         var reg = /.*\/([^\.\/]+)/g;    
  25.         var fileName=arr[i].picSrc.replace(reg,"$1");  
  26.         arr[i].picSrc='http://code.liuxinxiu.com/upload/user/'+fileName;   //重新赋值再转为JSON.字符串  
  27.         //console.log('http://code.liuxinxiu.com/upload/user/'+fileName);  //重新拼接  
  28.         //console.log(fileName); //正则获取最后一个字符    
  29.   
  30.     }    
  31. };  
  32. JSON.stringify(arr);  

适用于LINUX下批量下载图片

Tags:
第一页 上页 1 2 3 4 5 6 7 8 9 10 下页 最后页 [ 显示模式: 摘要 | 列表 ]