基于HTTP基础所提出的问题

一、GET和POST有什么区别?

(一)相同点

        HTTP 的底层是 TCP/IP。所以 GET 和 POST 的底层也是 TCP/IP,也就是说,GET 和 POST 都是 TCP 链接。所以说,它们的本质是相同的。

        GET 和 POST 之所以产生,要通过HTTP的规则和浏览器/服务器的限制进行区分,使它们在应用过程中体现出不同。

(二)区别

        1.作用不同

        GET 多用于从服务端获取资源

        POST 一般用来向服务端提交资源

        2.传参方式

        最直观:

        GET 的参数一般是通过 ? 跟在 URL 后面的,多个参数通过 & 连接,比如:www.example.com?serach=bianchengsanmei&content=123

        POST 的参数一般是包含在 request body 中。

        注意:这个区别不是绝对的,GET 也可以通过 params 携带参数,而 POST 的URL 后面也可以携带参数,只是我们通常不建议这么做而已。

        3.安全性不同

        GET POST 更不安全,因为参数直接暴露在URL上所以 GET 不能用来传递敏感信息。

        注意:从传输的角度来说,他们都是不安全的,因为 HTTP 在网络上是明文传输的,只要在网络节点上捉包就能完整地获取数据报文,要想安全传输,就只有加密,也就是 HTTPS

        4.参数长度限制不同

        GET传送的数据量较小,不能大于2KB

        POST传送的数据量较大,一般被默认为不受限制

        注意:HTTP 协议没有 Body 和 URL 的长度限制,对 URL 限制的大多是浏览器和服务器的原因。服务器处理长 URL 要消耗比较多的资源,为了性能和安全(防止恶意构造长 URL 来攻击)考虑,会给 URL 长度加限制。

        5.参数数据类型不同

        GET 只接受 ASCII 字符。

        POST 没有限制。

       6.编码方式不同

        GET 请求只能进行 URL 编码(application/x-www-form-urlencoded)

        POST 支持多种编码方式(application/x-www-form-urlencoded 或 multipart/form-data。为二进制数据使用多种编码

        7.缓存机制不同

        ①GET 请求会被浏览器主动cache,而 POST 不会,除非手动设置

        ②GET 请求参数会被完整保留在浏览器历史记录里,而 POST 中的参数不会被保留

        ③GET 产生的 URL 地址可以被收藏,而 POST 不可以

        ④GET 在浏览器回退时是无害的,而 POST 会再次提交请求

        8.时间消耗不同

        GET 产生一个 TCP 数据包。GET 方式的请求,浏览器会把 header data 一并发送出去,服务器响应 200(返回数据)。

        POST 产生两个 TCP 数据包。 POST方式的请求,浏览器先发送 Header,服务器响应 100 continue,浏览器再发送 data,服务器响应 200 ok(返回数据)。

二、POST为什么会发送两次❓

        浏览器在发送 POST 请求时,会先发送一个 OPTIONS 类型的预检请求,确认服务器是否支持实际的 POST 请求如果服务器返回了允许跨域请求的响应头部信息,浏览器才会继续发送 POST 请求。

      OPTIONS预检请求❓这是啥❓

                当出现跨域且为非简单请求,就会出现(Preflight)预检请求,也就是两次请求。

      非简单请求(preflight request)?那简单请求(simple request)呢?怎么区分?

                简单请求标准:

                        ①请求的方法只能是GETPOSTHEAD的一种

                        ②请求的header的只能是   Accept,  Accept-Language,    Content-LanguageContent-Type  这些字段,不能超出这些字段

                        ③对于请求的header的    Content-Type 字段,只能是值:text/plain、multipart/form-data、application/x-www-form-urlencoded。

                都满足以上条件的就是简单请求,否则就是非简单请求。 我们经常使用的    Content-Type:application/json; charset=utf-8,    这个请求就是非简单请求。

      为什么会发生预检请求❓ 

               因为跨域了,只有跨域的情况下,才会发生预请求。

三、跨域❓

      为啥会出现❓

        浏览器的同源策略限制。 同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的Javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)。

      那跨域是啥❓

        当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域。

基于HTTP基础所提出的问题_第1张图片

      非同源有那些限制? 

               1. 无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB

               2.无法接触非同源网页的 DOM

               3.无法向非同源地址发送 AJAX 请求

      解决方法

                方法 1:JQuery的ajax(仅推荐JQuery项目中使用)

function callback(){
    console.log("月薪一千五,心比美式苦")
}

$.ajax({
    url: 'http://www.domain2.com:8080/login',
    type: 'get',
    dataType: 'jsonp',  // 请求方式为jsonp  设置跨域的重点
    jsonpCallback: "callBack",  // 回调函数
});

                方法2:script标签解决跨域(远古web使用的方案,已不建议使用) 

  

                方法3:前端代理解决跨域 (项目中,使用Vite配置)

基于HTTP基础所提出的问题_第2张图片 

              方法4:服务端代理(Nginx代理)————简单配置模板

                安装Nginx服务器后,在安装目录里找到nginx.conf,根据模板进行配置。

# 全局参数
user nginx;              # Nginx进程运行用户
worker_processes auto;   # Nginx工作进程数,通常设置为CPU核数
error_log /var/log/nginx/error.log warn;    # 错误日志路径和日志级别
pid /run/nginx.pid;      # 进程PID保存路径

# 定义事件模块
events {
    worker_connections 1024;    # 每个工作进程最大并发连接数
    use epoll;                  # 使用epoll网络模型,提高性能
    multi_accept on;            # 开启支持多个连接同时建立
}

# 定义HTTP服务器模块
http {
    # 缓存文件目录
    client_body_temp_path /var/cache/nginx/client_temp;
    proxy_temp_path /var/cache/nginx/proxy_temp;
    fastcgi_temp_path /var/cache/nginx/fastcgi_temp;

    # 定义日志格式,main是默认的日志格式
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
        '$status $body_bytes_sent "$http_referer" '
        '"$http_user_agent" "$http_x_forwarded_for"';

    # 默认访问日志保存路径和格式
    access_log /var/log/nginx/access.log main;

    # 定义MIME类型
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    # 代理参数
    proxy_connect_timeout 6s;       # 连接超时时间
    proxy_send_timeout 10s;         # 发送超时时间
    proxy_read_timeout 10s;         # 接收超时时间
    proxy_buffer_size 16k;          # 缓冲区大小
    proxy_buffers 4 32k;            # 缓冲区个数和大小
    proxy_busy_buffers_size 64k;    # 忙碌缓冲区大小
    proxy_temp_file_write_size 64k; # 代理临时文件写入大小

    # 启用压缩,可以提高网站访问速度
    gzip on;
    gzip_min_length 1k;                    # 最小压缩文件大小
    gzip_types text/plain text/css application/json application/javascript application/xml;

    # 定义HTTP服务器
    server {
        listen 80;              # 监听端口

        server_name example.com;    # 域名

        # 重定向到HTTPS,强制使用HTTPS访问
        if ($scheme != "https") {
            return 301 https://$server_name$request_uri;
        }

        # HTTPS服务器配置
        ssl_certificate      /etc/nginx/ssl/server.crt;    # SSL证书路径
        ssl_certificate_key  /etc/nginx/ssl/server.key;    # SSL私钥路径

        # SSL会话缓存参数
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 10m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;

        # 配置代理路径
        location / {
            proxy_pass http://localhost:8080;        # 转发请求的目标地址
            proxy_set_header Host $host;             # 设置请求头中的Host字段
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                            # 设置HTTP头中的X-Forwarded-For字段,表示客户端真实IP,多个IP用逗号隔开
            proxy_set_header X-Real-IP $remote_addr; # 设置请求头中的X-Real-IP字段,表示客户端真实IP
        }

        # 配置静态文件访问路径
        location /static/ {
            alias /path/to/static/files/;   # 静态文件的目录
            expires 7d;                     # 静态文件缓存时间
            add_header Pragma public;       # 添加HTTP响应头
            add_header Cache-Control "public, must-revalidate, proxy-revalidate";
        }

        # 配置错误页面
        error_page 404 /404.html;           # 404错误页
        location = /404.html {
            internal;                       # 不接受外部访问
            root /usr/share/nginx/html;     # 404错误页文件所在目录
        }

        # 配置重定向
        location /old/ {
            rewrite ^/old/([^/]+) /new/$1 permanent;   # 将/old/xxx路径重定向为/new/xxx,返回301状态码
        }
    }

    # 其他服务配置
    # server {
    #     ...
    # }

    # 配置TCP负载均衡
    upstream backends {
        server backend1.example.com:8080 weight=5;  # 后端服务器地址和权重
        server backend2.example.com:8080;
        server backend3.example.com:8080 backup;   # 备用服务器
        keepalive 16;                               # 连接池大小
    }

    server {
        listen 80;
        server_name example.com;

        location / {
            proxy_pass http://backends;             # 负载均衡转发请求的目标地址
            proxy_set_header Host $host;            # 设置请求头中的Host字段
            proxy_set_header X-Real-IP $remote_addr; # 设置请求头中的X-Real-IP字段,表示客户端真实IP
        }
    }
}

               方法5:后台(逻辑层)添加响应头解决。(并不建议此种方案,因为安全性不高。自己写小练习的时候建议使用,因为真的很方便。)

                Access-Control-Allow-Origin  响应头的意思是,安全同行的请求。

                例如:

                http://192.168.0.103:8080 向http://192.168.0.102:8080 发送了请求,结果因为域名不一样,在返回信息的时候因为IP地址不一致被拦截

                但是如果http://192.168.0.102:8080 在响应头中的 Access-Control-Allow-Origin 字段中携带上属性值'http://192.168.0.103:8080' ,这就等于告诉浏览器,http://192.168.0.102:8080 这个地址是安全的,请不要拦截。这样,http://192.168.0.103:8080 就可以接受来自 http://192.168.0.102:8080 返回的信息。

第一种设置:http:/ /192.168.0.103:8080这个可以不受拦截
//响应头
Access-Control-Allow-Origin':'http:/ /192.168.0.103:8080'



第二种:所有都不拦截
//响应头
// * 代表所有域名均不拦截
Access-Control-Allow-Origin':'*'


你可能感兴趣的:(浏览器知识体系,http,网络,网络协议)