blog icon indicating copy to clipboard operation
blog copied to clipboard

跨域系列 - API Proxy 与 JSONP

Open HXWfromDJTU opened this issue 4 years ago • 0 comments

前言

前面一篇文章聊过了最常用的跨域手段 CORS (跨域资源共享)。这次再看看工作中其他的跨域资源获取手段,proxyJSONP

proxy

使用的场景

同源策略的是浏览器本身管理资源的安全策略,并且以域来划分管理。但是当企业发展、业务变得繁杂之后,一个页面需要的资源来源,可能是数十个。

与每个接口的提供方进行进行沟通,让其进行在响应中添加对应的 Access-Controll-Allow-xxxx 的响应头是在过于繁琐,万一自己网站的域名做了调整,又需要对所有的接口提供方进行更新。

解决的原理

通过一个中间服务器为我们的 web服务 进行请求转发。Proxy 与数据接口之间可以直接调用,Proxy Server 与 web应用 之间且存在的跨域问题,只需要使用一次 跨域响应头 的设置即可。

实现方案

Proxy Server 是一个最简化的 http Server,不进行任何的业务处理,只对请求原封不动地转发,对相应数据也原封不动地返回给请求方。

常用的实际方案是 Node.js 转发nginx 转发,为啥选她俩?因为足够轻量足够快,前端可以闭环。

cors-anywhere

cors-anywhere 是一个开箱即用的 Node.js 转发服务,专门为中转请求而设计。前端开发将其部署到自己的服务器上

return axios.get('https://cors-anywhere.your-server.com/https://api.other-domain.com/price', {
        params: { ids: tokens.join(',') },
        withCredentials: false,
    })

nginx 代理

#进程, 可更具cpu数量调整
worker_processes  1;

events {
    #连接数
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    #连接超时时间,服务器会在这个时间过后关闭连接。
    keepalive_timeout  10;

    # gizp压缩
    gzip  on;

    # 直接请求nginx也是会报跨域错误的这里设置允许跨域
    # 如果代理地址已经允许跨域则不需要这些, 否则报错(虽然这样nginx跨域就没意义了)
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Headers X-Requested-With;
    add_header Access-Control-Allow-Methods GET,POST,OPTIONS;

    # srever模块配置是http模块中的一个子模块,用来定义一个虚拟访问主机
    server {
        listen       80;
        server_name  localhost;
        
        # 根路径指到index.html
        location / {
            root   html;
            index  index.html index.htm;
        }

        # localhost/api 的请求会被转发到192.168.0.103:8080
        location /api/ {
            rewrite ^/b/(.*)$ /$1 break; # 去除本地接口/api前缀, 否则会出现404
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass ?; # 转发地址
        }
        
        # 重定向错误页面到/50x.html
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }

}

JSONP

假设代理服务始终是麻烦的,JSONP 方案的灵活性这体现了出来。淘宝、天猫、京东的等电商网站的首页数据,无一例外地使用了 JSONP 的数据请求方式。

原理则是“欺骗浏览器”,告诉浏览器我用换这个script 标签获取回来的只是一些执行脚本,并不是数据,而让浏览器不进行资源访问的域限制。

缺点

  • 只能够使用 GET 请求
  • 由于安全性的限制,一般只能设计为对服务器无损的数据请求
  • 因为要拼接在返回的函数毁掉中,承载的数据量相对比较小

优点

  • 浏览器的兼容性更好

参考资料

[1] JSONP - Wikipedia
[2] 跨源资源共享(CORS) - MDN

HXWfromDJTU avatar Nov 07 '20 14:11 HXWfromDJTU