网络技术

3proxy 使用教程(转)

发布于 2018年11月06日

转自:3proxy 使用指北 (by wsgzao)

Comments (2)

网络技术

RESTful API 最佳实践(转)

发布于 2018年10月10日

一、URL 设计

1.1 动词 + 宾语

RESTful 的核心思想就是,客户端发出的数据操作指令都是”动词 + 宾语”的结构。比如,GET /articles这个命令,GET是动词,/articles是宾语。

动词通常就是五种 HTTP 方法,对应 CRUD 操作。

  • GET:读取(Read)
  • POST:新建(Create)
  • PUT:更新(Update)
  • PATCH:更新(Update),通常是部分更新
  • DELETE:删除(Delete)

根据 HTTP 规范,动词一律大写。

1.2 动词的覆盖

有些客户端只能使用GETPOST这两种方法。服务器必须接受POST模拟其他三个方法(PUTPATCHDELETE)。

这时,客户端发出的 HTTP 请求,要加上X-HTTP-Method-Override属性,告诉服务器应该使用哪一个动词,覆盖POST方法。


POST /api/Person/4 HTTP/1.1  
X-HTTP-Method-Override: PUT

上面代码中,X-HTTP-Method-Override指定本次请求的方法是PUT,而不是POST

1.3 宾语必须是名词

宾语就是 API 的 URL,是 HTTP 动词作用的对象。它应该是名词,不能是动词。比如,/articles这个 URL 就是正确的,而下面的 URL 不是名词,所以都是错误的。

  • /getAllCars
  • /createNewCar
  • /deleteAllRedCars

1.4 复数 URL

既然 URL 是名词,那么应该使用复数,还是单数?

这没有统一的规定,但是常见的操作是读取一个集合,比如GET /articles(读取所有文章),这里明显应该是复数。

为了统一起见,建议都使用复数 URL,比如GET /articles/2要好于GET /article/2

1.5 避免多级 URL

常见的情况是,资源需要多级分类,因此很容易写出多级的 URL,比如获取某个作者的某一类文章。


GET /authors/12/categories/2

这种 URL 不利于扩展,语义也不明确,往往要想一会,才能明白含义。

更好的做法是,除了第一级,其他级别都用查询字符串表达。


GET /authors/12?categories=2

下面是另一个例子,查询已发布的文章。你可能会设计成下面的 URL。


GET /articles/published

查询字符串的写法明显更好。


GET /articles?published=true

二、状态码

2.1 状态码必须精确

客户端的每一次请求,服务器都必须给出回应。回应包括 HTTP 状态码和数据两部分。

HTTP 状态码就是一个三位数,分成五个类别。

  • 1xx:相关信息
  • 2xx:操作成功
  • 3xx:重定向
  • 4xx:客户端错误
  • 5xx:服务器错误

这五大类总共包含100多种状态码,覆盖了绝大部分可能遇到的情况。每一种状态码都有标准的(或者约定的)解释,客户端只需查看状态码,就可以判断出发生了什么情况,所以服务器应该返回尽可能精确的状态码。

API 不需要1xx状态码,下面介绍其他四类状态码的精确含义。

2.2 2xx 状态码

200状态码表示操作成功,但是不同的方法可以返回更精确的状态码。

  • GET: 200 OK
  • POST: 201 Created
  • PUT: 200 OK
  • PATCH: 200 OK
  • DELETE: 204 No Content

上面代码中,POST返回201状态码,表示生成了新的资源;DELETE返回204状态码,表示资源已经不存在。

此外,202 Accepted状态码表示服务器已经收到请求,但还未进行处理,会在未来再处理,通常用于异步操作。下面是一个例子。


HTTP/1.1 202 Accepted

{
  "task": {
    "href": "/api/company/job-management/jobs/2130040",
    "id": "2130040"
  }
}

2.3 3xx 状态码

API 用不到301状态码(永久重定向)和302状态码(暂时重定向,307也是这个含义),因为它们可以由应用级别返回,浏览器会直接跳转,API 级别可以不考虑这两种情况。

API 用到的3xx状态码,主要是303 See Other,表示参考另一个 URL。它与302307的含义一样,也是”暂时重定向”,区别在于302307用于GET请求,而303用于POSTPUTDELETE请求。收到303以后,浏览器不会自动跳转,而会让用户自己决定下一步怎么办。下面是一个例子。


HTTP/1.1 303 See Other
Location: /api/orders/12345

2.4 4xx 状态码

4xx状态码表示客户端错误,主要有下面几种。

400 Bad Request:服务器不理解客户端的请求,未做任何处理。

401 Unauthorized:用户未提供身份验证凭据,或者没有通过身份验证。

403 Forbidden:用户通过了身份验证,但是不具有访问资源所需的权限。

404 Not Found:所请求的资源不存在,或不可用。

405 Method Not Allowed:用户已经通过身份验证,但是所用的 HTTP 方法不在他的权限之内。

410 Gone:所请求的资源已从这个地址转移,不再可用。

415 Unsupported Media Type:客户端要求的返回格式不支持。比如,API 只能返回 JSON 格式,但是客户端要求返回 XML 格式。

422 Unprocessable Entity :客户端上传的附件无法处理,导致请求失败。

429 Too Many Requests:客户端的请求次数超过限额。

2.5 5xx 状态码

5xx状态码表示服务端错误。一般来说,API 不会向用户透露服务器的详细信息,所以只要两个状态码就够了。

500 Internal Server Error:客户端请求有效,服务器处理时发生了意外。

503 Service Unavailable:服务器无法处理请求,一般用于网站维护状态。

三、服务器回应

3.1 不要返回纯本文

API 返回的数据格式,不应该是纯文本,而应该是一个 JSON 对象,因为这样才能返回标准的结构化数据。所以,服务器回应的 HTTP 头的Content-Type属性要设为application/json

客户端请求时,也要明确告诉服务器,可以接受 JSON 格式,即请求的 HTTP 头的ACCEPT属性也要设成application/json。下面是一个例子。


GET /orders/2 HTTP/1.1 
Accept: application/json

3.2 发生错误时,不要返回 200 状态码

有一种不恰当的做法是,即使发生错误,也返回200状态码,把错误信息放在数据体里面,就像下面这样。


HTTP/1.1 200 OK
Content-Type: application/json

{
  "status": "failure",
  "data": {
    "error": "Expected at least two items in list."
  }
}

上面代码中,解析数据体以后,才能得知操作失败。

这张做法实际上取消了状态码,这是完全不可取的。正确的做法是,状态码反映发生的错误,具体的错误信息放在数据体里面返回。下面是一个例子。


HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "error": "Invalid payoad.",
  "detail": {
     "surname": "This field is required."
  }
}

3.3 提供链接

API 的使用者未必知道,URL 是怎么设计的。一个解决方法就是,在回应中,给出相关链接,便于下一步操作。这样的话,用户只要记住一个 URL,就可以发现其他的 URL。这种方法叫做 HATEOAS。

举例来说,GitHub 的 API 都在 api.github.com 这个域名。访问它,就可以得到其他 URL。


{
  ...
  "feeds_url": "https://api.github.com/feeds",
  "followers_url": "https://api.github.com/user/followers",
  "following_url": "https://api.github.com/user/following{/target}",
  "gists_url": "https://api.github.com/gists{/gist_id}",
  "hub_url": "https://api.github.com/hub",
  ...
}

上面的回应中,挑一个 URL 访问,又可以得到别的 URL。对于用户来说,不需要记住 URL 设计,只要从 api.github.com 一步步查找就可以了。

HATEOAS 的格式没有统一规定,上面例子中,GitHub 将它们与其他属性放在一起。更好的做法应该是,将相关链接与其他属性分开。


HTTP/1.1 200 OK
Content-Type: application/json

{
  "status": "In progress",
   "links": {[
    { "rel":"cancel", "method": "delete", "href":"/api/status/12345" } ,
    { "rel":"edit", "method": "put", "href":"/api/status/12345" }
  ]}
}

四、参考链接

(完)

来源出处:阮一峰 http://www.ruanyifeng.com/blog/2018/10/restful-api-best-practices.html

Comments (1)

网络技术

linux系统禁ping及改ssh端口

发布于 2017年10月25日

#禁ping操作#

1、修改文件

echo 1 >/proc/sys/net/ipv4/icmp_echo_ignore_all

即可

如果需要ping通则输入:

echo 0 >/proc/sys/net/ipv4/icmp_echo_ignore_all

该命令重启后会失效,所以应该让其开机后自动运行

echo "echo 1 >/proc/sys/net/ipv4/icmp_echo_ignore_all" >>/etc/rc.d/rc.local

2、也可以通过iptables来配置

①允许PING设置

iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT

或者也可以临时停止防火墙操作的。

service iptables stop

②禁止PING设置

iptables -A INPUT -p icmp --icmp-type 8 -s 0/0 -j DROP

#修改ssh端口#

1、修改文件

vim /etc/ssh/sshd_config

找到#Port 22,将其修改为其他端口,不建议使用常用端口,80 21 443 3306等等。

2、然后后重启服务,

Centos6.x系统,

/etc/init.d/sshd restart

Centos7.x系统,

systemctl restart sshd.service

Comments (0)

网络技术

密码保护:出场教程

发布于 2017年10月24日

这是一篇受密码保护的文章,您需要提供访问密码:

要查看留言请输入您的密码。

SEO

[已招到]招聘SEO,坐标南京

发布于 2017年10月10日

——————————update 2018.4——————————————

已招到!

 

——————————update 2017.11——————————————

还缺一人。。

We Need You!

发一则招聘,南京地区

招SEO,比较着急。

公司:house365

人数:1

要求:一年以上SEO工作经验

大站SEO操作的机会来了,筒子们有简历请发simonsww@qq.com,注明来自博客。

 

Comments (0)

网络技术

winhttp api和com对象版区别

发布于 2017年05月10日

到底该用哪个接口,微软这么说,api方式:功能齐全,不过调用复杂些;com接口,调用简单,属于一个封装,有部分功能缺失。https://msdn.microsoft.com/zh-cn/library/aa383158(v=vs.85).aspx

C/C++ API COM interface
Advantages
  • Responses can be processed in chunks, which is more efficient.
  • POST operations can also be processed in chunks, speeding processing time.
  • AutoProxy support.
  • Access to the full feature set of WinHTTP.
  • Binary data can easily be handled.
  • Creating an application is easy and requires fewer lines of code than the C/C++ API.
  • The interface can be used by scripting languages.
Disadvantages
  • Processing is more complex.
  • The C/C++ API requires more steps than the COM interface to perform the same actions.
  • Setting up a request takes more code.
  • The COM interface does not provide access to the full feature set of WinHTTP.
  • It is difficult to handle binary data types in some scripting languages, such as VBScript and JScript.
  • The COM interface does not support AutoProxy.
  • Applications must use the COM APARTMENT_THREADED model.
  • Before a response can begin being processed, the entire response must first be received and buffered.

Comments (0)

网络技术

密码保护:Mindjet MindManager2016 可用版

发布于 2017年03月06日

这是一篇受密码保护的文章,您需要提供访问密码:

密码保护:Mindjet MindManager2016 可用版已关闭评论

wocale

Life

杂记:从2016躺到2017

发布于 2017年01月16日

近况:整整一年多没更新这了,2016这一年发生的事可谓是前几年的N倍多。。换工作了(每周加班到飞起),买房卖房再买房,很多事情也确定了。嗯,对,还有我的膝盖碰伤过三次。。

一直也没有抽出时间来整理自己的很多事情,包括新想法、软件、项目、创业等等。我擦嘞,事业心貌似有点颓,怎么感觉最近说话也不利索了。。

2016灰常忙,但属于瞎忙。。做了几个稍微大点的项目,不过效果一般,无疾而终。。

最近一个多月在写一个轮子,不过思路僵化,没太多进展,然后这两天发现有现成的轮子可以用,而且人家已经非常成熟,而且系统自带的勉强也能用,换个变量类型就好了。。当时我内心就是这样:

看来还是要经常写点东西,哪怕是记录也好、总结也好,终归没有太多坏处,还能反省自己。。

接下来就是看成果的时候,慢慢来更~~

2017……(发誓:我不会等到2018再更新的。。)

Comments (4)

网络技术

lnmp下mysql 5.6内存占用过高解决方法

发布于 2015年11月02日

最新的lnmp一键包1.2里,可以选择mysql5.6版本安装,但是最近发现mysql有时候会出现挂掉的情况,看一下mysql错误日志,应该是内存占满导致的,1G内存的vps是伤不起的。。

重启mysql服务后,top一下发现这一个mysql服务就占用了500多MB内存。。

Google一番,贴一下记录:

mysql5.6的默认配置是不适合小型站点的,win的话在my.ini里修改、linux则在/etc/my.cnf里修改performance_schema_max_table_instances参数,有就修改,没有就追加:

performance_schema_max_table_instances=400
table_definition_cache=400
table_open_cache=256

修改完毕后,重启mysql服务,service mysql restart,然后top后发现内存占用少了一半,应该还有很大优化空间,鉴于内存基本够用了,就不继续折腾了。

Comments (3)

网络技术

excel中批量添加带图片批注的vba宏命令

发布于 2015年06月04日

应用场景

1、在excel中,有很多型号的产品名称,需要鼠标悬浮到某产品型号上自动在excel中显示对应的图片,用来对比筛选

2、公司举行某活动,需要对用户反馈的图片进行人工甄选、审查等等,具体用途可以拓展。

使用方法

为下面宏命令添加快捷键,可将其导出为加载宏,在excel中调用该加载宏,使用快捷键即可批量快速给目标单元格加上图片批注。

宏命令如下:


'***************************************************
'* 加载宏:excel图片批量添加批注功能
'* 功能描述:对本地文档里图片,自动进行对应至excel中单元格
'* 作 者:simon
'* 作者博客:sunweiwei.com
'* 日 期:2015-6-4
'* 版 本:V1.0.0
'***************************************************
'整行注释的为在读取图片尺寸时不需要的文件头信息
'BMP文件头
Private Type BitmapFileHeader
bfType As Integer '标识 0,1 两个字节为 42 4D 低位在前,即 19778
bfReserved2 As Integer
bfOffBits As Long
bfReserved1 As Integer
bfSize As Long
End Type
Private Type BitmapInfoHeader
biSize As Long
biWidth As Long '宽度 18,19,20,21 四个字节,低位在前
biHeight As Long '高度 22,23,24,25 四个字节,低位在前
' biPlanes As Integer
' biBitCount As Integer
' biCompression As Long
' biSizeImage As Long
' biXPelsPerMeter As Long
' biYPelsPerMeter As Long
' biClrUsed As Long
' biClrImportant As Long
End Type
'JPEG(这个好麻烦)
Private Type LSJPEGHeader
jSOI As Integer '图像开始标识 0,1 两个字节为 FF D8 低位在前,即 -9985
jAPP0 As Integer 'APP0块标识 2,3 两个字节为 FF E0
jAPP0Length(1) As Byte 'APP0块标识后的长度,两个字节,高位在前
' jJFIFName As Long 'JFIF标识 49(J) 48(F) 44(I) 52(F)
' jJFIFVer1 As Byte 'JFIF版本
' jJFIFVer2 As Byte 'JFIF版本
' jJFIFVer3 As Byte 'JFIF版本
' jJFIFUnit As Byte
' jJFIFX As Integer
' jJFIFY As Integer
' jJFIFsX As Byte
' jJFIFsY As Byte
End Type
Private Type LSJPEGChunk
jcType As Integer '标识(按顺序):APPn(0,1~15)为 FF E1~FF EF; DQT为 FF DB(-9217)
'SOFn(0~3)为 FF C0(-16129),FF C1(-15873),FF C2(-15617),FF C3(-15361)
'DHT为 FF C4(-15105); 图像数据开始为 FF DA
jcLength(1) As Byte '标识后的长度,两个字节,高位在前
'若标识为SOFn,则读取以下信息;否则按照长度跳过,读下一块
jBlock As Byte '数据采样块大小 08 or 0C or 10
jHeight(1) As Byte '高度两个字节,高位在前
jWidth(1) As Byte '宽度两个字节,高位在前
' jColorType As Byte '颜色类型 03,后跟9字节,然后是DHT
End Type
'PNG文件头
Private Type LSPNGHeader
pType As Long '标识 0,1,2,3 四个字节为 89 50(P) 4E(N) 47(G) 低位在前,即 1196314761
pType2 As Long '标识 4,5,6,7 四个字节为 0D 0A 1A 0A
pIHDRLength As Long 'IHDR块标识后的长度,疑似固定 00 0D,高位在前,即 13
pIHDRName As Long 'IHDR块标识 49(I) 48(H) 44(D) 52(R)
Pwidth(3) As Byte '宽度 16,17,18,19 四个字节,高位在前
Pheight(3) As Byte '高度 20,21,22,23 四个字节,高位在前
' pBitDepth As Byte
' pColorType As Byte
' pCompress As Byte
' pFilter As Byte
' pInterlace As Byte
End Type
'GIF文件头(这个好简单)
Private Type LSGIFHeader
gType1 As Long '标识 0,1,2,3 四个字节为 47(G) 49(I) 46(F) 38(8) 低位在前,即 944130375
gType2 As Integer '版本 4,5 两个字节为 7a单幅静止图像9a若干幅图像形成连续动画
gWidth As Integer '宽度 6,7 两个字节,低位在前
gHeight As Integer '高度 8,9 两个字节,低位在前
End Type
Public Function PictureSize(ByVal picPath As String, ByRef Width As Long, ByRef Height As Long) As String
Dim iFile As Integer
Dim jpg As LSJPEGHeader
Width = 0: Height = 0 '预输出:0 * 0
If picPath = "" Then PictureSize = "null": Exit Function '文件路径为空
If Dir(picPath) = "" Then PictureSize = "not exist": Exit Function '文件不存在
PictureSize = "error" '预定义:出错
iFile = FreeFile()
Open picPath For Binary Access Read As #iFile
Get #iFile, , jpg
If jpg.jSOI = -9985 Then
Dim jpg2 As LSJPEGChunk, pass As Long
pass = 5 + jpg.jAPP0Length(0) * 256 + jpg.jAPP0Length(1) '高位在前的计算方法
PictureSize = "JPEG error" 'JPEG分析出错
Do
Get #iFile, pass, jpg2
If jpg2.jcType = -16129 Or jpg2.jcType = -15873 Or jpg2.jcType = -15617 Or jpg2.jcType = -15361 Then
Width = jpg2.jWidth(0) * 256 + jpg2.jWidth(1)
Height = jpg2.jHeight(0) * 256 + jpg2.jHeight(1)
PictureSize = Width & "*" & Height
'PictureSize = "JPEG" 'JPEG分析成功
'Stop
Exit Do
End If
pass = pass + jpg2.jcLength(0) * 256 + jpg2.jcLength(1) + 2
Loop While jpg2.jcType <> -15105 'And pass < LOF(iFile)
ElseIf jpg.jSOI = 19778 Then
Dim bmp As BitmapInfoHeader
Get #iFile, 15, bmp
Width = bmp.biWidth
Height = bmp.biHeight
PictureSize = Width & "*" & Height
' PictureSize = "BMP" 'BMP分析成功
Else
Dim png As LSPNGHeader
Get #iFile, 1, png
If png.pType = 1196314761 Then
Width = png.Pwidth(0) * 16777216 + png.Pwidth(1) * 65536 + png.Pwidth(2) * 256 + png.Pwidth(3)
Height = png.Pheight(0) * 16777216 + png.Pheight(1) * 65536 + png.Pheight(2) * 256 + png.Pheight(3)
PictureSize = Width & "*" & Height
'PictureSize = "PNG" 'PNG分析成功
ElseIf png.pType = 944130375 Then
Dim gif As LSGIFHeader
Get #iFile, 1, gif
Width = gif.gWidth
Height = gif.gHeight
PictureSize = Width & "*" & Height
'PictureSize = "GIF" 'GIF分析成功
Else
PictureSize = "unknow" '文件类型未知
End If
End If
Close #iFile
End Function
'*************************
Sub 添加图片批注()
Dim 单元格
Dim w As Long, h As Long
Dim f As String '图片文件完成路径
Dim t As String
Dim Pwidth As Long, Pheight As Long
Dim Psize As String
On Error Resume Next
For Each 单元格 In Selection
单元格.AddComment
单元格.Comment.Shape.Fill.UserPicture ActiveWorkbook.Path & "\pic\" & Replace(单元格.Value, "[图片]", "") & ".jpg"
f = ActiveWorkbook.Path & "\pic\" & Replace(单元格.Value, "[图片]", "") & ".jpg" '图片文件完成路径
Psize = PictureSize(f, w, h) '运行宏,w,h就是对应图片的width height ,返回 width*height
If Len(Psize) > 0 Then
Pwidth = Val(Split(Psize, "*")(0)) '返回 图片 宽
Pheight = Val(Split(Psize, "*")(1)) '返回 图片 高
End If
单元格.Comment.Shape.Height = Pheight / 4
单元格.Comment.Shape.Width = Pwidth / 4
Next 单元格
End Sub

Comments (2)

SEE MORE ARTICLES IN THE ARCHIVE

个人软件, 推荐阅读

斗牛百度实时指数&历史数据批量获取工具(2019年)已更新,支持各城市、PC、移动端历史数据采集,附常见问题解答!

自从发布了早期版本的百度指数查询工具后,就陆续收到各种邮件询问什么注册码的,为什么不给注册码、怎么使用、如何操 […]

阅读全文

推荐阅读, 网络技术

Amazon EC2的V-P-N-PPTP搭建教程(on aws redhat6.5 X64)

前些日子收到amazon的邮件通知,一年前申请的ec2到期了,一年免费的free tier没有了,放在上面的2 […]

阅读全文

推荐阅读, 网络技术

谷歌全球IP奉上!

目前谷歌已经被全面封锁了,日常工作中多少还是会受影响的,特别是想找个资料啥的,能急死你。。 现奉上谷歌全球39 […]

阅读全文

斗牛SEO工具