Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

网络编程 #37

Open
ShannonChenCHN opened this issue Apr 27, 2017 · 17 comments
Open

网络编程 #37

ShannonChenCHN opened this issue Apr 27, 2017 · 17 comments

Comments

@ShannonChenCHN
Copy link
Owner

ShannonChenCHN commented Apr 27, 2017

  • 网络编程基本原理
  • HTTP 协议与 HTTPS
    • HTTP 状态码
  • Cookie
  • TCP/IP
  • Socket 编程
  • DNS
  • 异常处理
  • 离线发送
  • 弱网络
  • 缓存
  • 流量
  • 即时通讯
  • 通信协议
    • 通信协议
    • 增量更新
  • 移动端网络层的设计
  • 网络请求性能优化、监控
  • 网络请求安全
    • HTTPS
    • 对称加密和非对称加密
    • DNS 劫持
    • Authentication
    • ATS(App Transport Security)
  • 数据交换格式
    • JSON(NSJSONSerialization)
    • XML
    • Protobuf
  • ipv4,ipv6
  • URL Loading System
  • 相关框架和类
    • NSURL、NSURLComponent
    • 系统:NSURLSession、 NSURLConnection、CFNetwork、CFSocket
    • 第三方:AFNetworking、MKNetworkKit、ASIHTTPRequest、Alamofire
  • 测试
  • 网络层架构设计

相关专题:

@ShannonChenCHN
Copy link
Owner Author

ShannonChenCHN commented Jun 28, 2017

聊聊 Cookie

Cookie 的跨域问题

关联主题:JavaScript 跨域

Cookie 的大小和数量限制

Cookie 的由来,cookie 的作用

服务端与客户端的交互中,如何处理 cookie?

客户端登录成功后,保存了 server 返回的 header 中的 cookie,以后再发起请求时,在 header 中将 cookie 带过去。

服务端在接收请求时,需要 cookie 中的哪些信息呢?

cookie 过期是怎么处理的?

cookie 中哪些属性是必需的?哪些是可选的?

属性 作用
name (必要) 要创建或覆盖的cookie的名字 (string)。
value (必要) cookie的值 (string)。
end (可选) 最大年龄的秒数 (一年为31536e3, 永不过期的cookie为Infinity) ,或者过期时间的GMTString格式或Date对象; 如果没有定义则会在会话结束时过期 (number – 有限的或 Infinity – string, Date object or null)。
path (可选) 例如 '/', '/mydir'。 如果没有定义,默认为当前文档位置的路径。(string or null)。路径必须为绝对路径(参见 RFC 2965)。关于如何在这个参数使用相对路径的方法请参见这段。
domain (可选) 例如 'example.com', '.example.com' (包括所有子域名), 'subdomain.example.com'。如果没有定义,默认为当前文档位置的路径的域名部分 (string或null)。
secure (可选) cookie只会被https传输 (boolean或null)。

cookie 会在什么情况下需要更更新呢?是不是客户端在每次请求时都要更新 cookie 呢?

This way, the server knows that this request is related to the previous one. The server would answer by sending the requested page, possibly including more Set-Cookie headers in the response in order to add new cookies, modify existing cookies, or delete cookies.

The value of a cookie can be modified by the server by including a Set-Cookie header in response to a page request. The browser then replaces the old value with the new value.

iOS 中 cookie 的处理

  • NSCookieStorage
  • Web view
  • 原生请求

问题

1. 虽然服务端返回的 cookie 在浏览器的 dev tools 中可以看到,但是执行 document.cookie 却看不到

这是因为服务端返回的 cookie 的 httponly 被设为 true 了,所以在 JavaScript 中无法通过 document.cookie 获取到,但是在后续的请求中会自动带上。

参考:


延伸阅读:

@ShannonChenCHN ShannonChenCHN changed the title 【专题】网络编程 网络编程 Jul 2, 2017
@ShannonChenCHN
Copy link
Owner Author

ShannonChenCHN commented Dec 12, 2017

@ShannonChenCHN
Copy link
Owner Author

ShannonChenCHN commented Dec 18, 2017

文件上传和下载,断点续传

  • 断点下载如何实现?(知识点:HTTP 请求头中的 range)
  • 后台下载

参考:

@ShannonChenCHN
Copy link
Owner Author

ShannonChenCHN commented Jan 9, 2018

@ShannonChenCHN
Copy link
Owner Author

ShannonChenCHN commented Jan 30, 2018

HTTP 协议中 GET 和 POST 的区别

  1. 最直观的就是语义上的区别,GET 用于获取数据,POST 用于提交数据。GET 的语义是请求获取指定的资源。GET 方法是幂等、可缓存的(除非有 Cache-ControlHeader的约束), GET 方法的报文主体没有任何语义。POST 的语义是根据请求负荷(报文主体)对指定的资源做出处理,具体的处理方式视资源类型而不同。POST 不幂等,(大部分实现)不可缓存。

  2. get参数有长度限制(受限于url长度,具体的数值取决于浏览器和服务器的限制),而post无限制。

注:在 Http1.1 协议中并没有提出针对URL的长度进行限制,但是Web服务器和浏览器对URI都有自己的长度限制。

参考:

@ShannonChenCHN
Copy link
Owner Author

网络传输数据存储格式

  • JSON
  • XML
  • Protocol Buffer

参考:

@ShannonChenCHN
Copy link
Owner Author

URL 中如何传递带数组的参数?

@ShannonChenCHN
Copy link
Owner Author

@ShannonChenCHN
Copy link
Owner Author

ShannonChenCHN commented Feb 23, 2018

HTTP 中的 Keep-Alive,pipelining 和多路复用

1. 什么是 Keep-Alive

HTTP 持久连接(HTTP persistent connection,也称作HTTP keep-alive或HTTP connection reuse)是使用同一个TCP连接来发送和接收多个HTTP请求/应答,而不是为每一个新的请求/应答打开新的连接的方法。

在 HTTP 1.1 中 所有的连接默认都是持续连接,除非特殊声明不支持。在 HTTP 1.0 中, 没有官方的 keepalive 的操作。通常是在现有协议上添加一个指数。如果浏览器支持 keep-alive,它会在请求的包头中添加:

Connection: Keep-Alive

900px-http_persistent_connection svg

参考:

2. HTTP pipelining

HTTP管线化(英语:HTTP pipelining)是将多个HTTP请求(request)整批提交的技术,而在发送过程中不需先等待服务端的回应。

缺陷:在宽带连接中,加速不是那么显著的,因为需要服务器端应用 HTTP/1.1 协议——服务器端必须按照客户端的请求顺序恢复请求,这样整个连接还是先进先出的,队头阻塞(HOL blocking)可能会发生,造成延迟。

800px-http_pipelining svg

参考:

3. Keep-Alive 和 HTTP pipelining 的区别

Keep-Alive 条件下,新请求只能在上一个请求返回时才能发出。
HTTP pipelining 条件下,可以多个请求并发(但是返回时依然是按照先进先出的规则)。

Keep-Alive 是大多数浏览器默认支持的,而 pipelining 却恰恰相反。

xkeepalive-pipelining png pagespeed ic ge_sabu9_q

参考:

4. 多路复用(Multiplexing)

  • 多路复用是 HTTP/2 协议中新增的一个新特性
  • 多路复用,即连接共享,即每一个request都是是用作连接共享机制的。一个request对应一个id,这样一个连接上可以有多个request,每个连接的request可以随机的混杂在一起,接收方可以根据request的 id将request再归属到各自不同的服务端请求里面。
  • HTTP2 的请求的TCP的connection一旦建立,后续请求以 stream的方式发送。每个 stream 的基本组成单位是frame(二进制帧),每种 frame又分为很多种类型例如HEADERS Frame(头部帧),DATA Frame(内容帧)等等。请求头 HEADERS Frame 组成了resquest,返回头 HEADERS Frame和DATA Frame组成了response,request和response组成了一个stream。

kp3

参考:

5. 多路复用和 HTTP pipelining 的区别

虽然 HTTP pipelining 和多路复用一样,都支持并发请求,但是 HTTP pipelining 条件下,多个请求之间的响应会被阻塞的,所以 pipeline 至今也没有被普及应用,而 HTTP/2 的多路复用则做到了真正的并发请求。同时,流还支持优先级和流量控制。

当流并发时,就会涉及到流的优先级和依赖。优先级高的流会被优先发送。图片请求的优先级要低于 CSS 和 SCRIPT,这个设计可以确保重要的东西可以被优先加载完。这一点是 HTTP pipelining 所不支持的。

http2request

参考:

@ShannonChenCHN
Copy link
Owner Author

ShannonChenCHN commented Feb 24, 2018

网络调试

1. DNS 域名解析

nslookup http://www.zhihu.com

或者

dig http://www.zhihu.com

参考:nslookup命令用法?

2. 使用 curl 命令获取 web 内容

curl http://www.zhihu.com

参考:curl - 百度百科

3. 使用 tcpdump 来查看网络数据包

sudo tcpdump host 123.59.141.154

参考:

@ShannonChenCHN
Copy link
Owner Author

ShannonChenCHN commented Feb 28, 2018

@ShannonChenCHN
Copy link
Owner Author

ShannonChenCHN commented Mar 22, 2018

Socket 编程

参考

@ShannonChenCHN
Copy link
Owner Author

HTTP 状态码

分类 分类描述
1** 信息,服务器收到请求,需要请求者继续执行操作
2** 成功,操作被成功接收并处理
3** 重定向,需要进一步的操作以完成请求
4** 客户端错误,请求包含语法错误或无法完成请求
5** 服务器错误,服务器在处理请求的过程中发生了错误

参考:

@ShannonChenCHN
Copy link
Owner Author

ShannonChenCHN commented Oct 17, 2018

如何在 Mac 上配置一个本地 Web 服务器

我们为什么需要服务器?

1. 本地文件 VS. 远程文件

通常情况下,你可以通过在浏览器中直接打开或者通过一个 URL 来访问一个文件。

使用浏览器访问本地文件时,一般地址是 file:// 开头的本地文件地址。
而访问远程文件时,一般地址是 http:// 或者 https:// 开头的地址,表示这个文件通过 http 协议访问的。

2. 测试本地文件存在的问题

在有些情况下,你打开一个本地的 html 文件时,会出现运行错误。

导致这些错误的原因主要有以下两个:
(1) 其中包含了异步请求。 如果你直接打开本地文件运行,一些浏览器(包括 Chrome)将不会运行其中的异步请求(请参阅 从服务器获取数据)。 这是因为安全限制而导致的(更多关于 Web 安全的信息,请参阅Website security)。

比如,你直接在浏览器中打开含有如下内容的文件:

<html>
<head>
    <script>
	    var request = new XMLHttpRequest(); 

		request.onreadystatechange = function () { 
		    console.log(request);
		}

		// 发送请求:
		request.open('GET', './data.json');
		request.send();
    </script>
    <title>HTML 测试页面</title>
</head>

<body>
    <p>测试页面</p>
</body>

</html>

然后,你会在 console 中看到这样的错误:

index.html:12 Failed to load file:///Users/ShannonChen/Desktop/Playground/nodejs_example/data.json: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.

(2) 执行文件中的代码时需要通过执行一些附加逻辑(如 PHP 或 Python)才能获得结果,而不仅仅是直接访问一个文件。

比如,我登录了京东网站后,查看购物车页面时,需要服务器返回的是包含我的购物车数据的页面,这个时候,就需要服务端在接收到请求后,跟我的用户信息(一般是 cookie)来返回匹配的数据。

方法一、启动 Mac 自带的 Apache 服务器

  1. 运行 Apache $ sudo apachectl start
  2. 退出 Apache $ sudo apachectl stop
  3. 把工程文件夹放到以下位置中 /Library/WebServer/Documents
  4. 在浏览器中访问:在地址栏中输入地址 http://localhost/工程文件夹名称/,回车。

注意: 不再需要使用后一定要记得退出,否则会消耗电脑性能。

Q:如何修改 Apache 的默认端口?
A:首先,找到 Apache 的配置文件,位于 /etc/apache2 下的 httpd.conf
然后,找到 Listen 80 那一行,修改成你想要的端口即可。

方法二:借助 Mac 系统自带的 Python,使用其中的 SimpleHTTPServer 模块启动服务器

  1. 安装 Python,其实 Mac 系统就自带了 Python2.7。
  2. 通过 cd <your-working-dir> 进入到你的工作目录下,也就是你要让别人访问的文件所在的目录。
  3. 在工作目录下执行下面的命令后,就可以启动服务了:
# 如果你的 Python 版本是 3.X
python3 -m http.server

# 如果你的 Python 版本是 2.X
python -m SimpleHTTPServer
  1. 默认情况下,上面的操作将会在本地 Web 服务器上的端口 8000 上运行工作目录中的内容。您可以通过在浏览器中输入 URL http://localhost:8000 并回车,来访问此服务器。你会看到列出的目录的内容,点击就可以查看你想运行的 HTML 文件。

Q:如何修改服务器的默认端口?
A:可以通过运行下面的命令来指定一个端口号:

# 如果你的 Python 版本是 3.X
python -m http.server <your-port> 

# 如果你的 Python 版本是 2.X
python -m SimpleHTTPServer <your-port> 

结论

方法二相比方法一来说,更简单、方便,也更灵活,而且还可以随时在终端上看到服务器的状态。

参考

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant