CORS跨域问题的解决方法

基础概念

同源策略:同一协议,同一域名,同一端口号。只要不满足三者其中一种都是属于跨域问题。

举几个简单的例子

1: https://www.a.com:8080http://www.a.com:8080的请求会出现跨域(域名、端口相同但协议不同)

2: https://www.a.com:8080https://www.b.com:8080的请求会出现跨域(协议、端口相同但域名不同)

3: https://www.a.com:8080https://www.a.com:9090的请求会出现跨域(协议、域名相同但端口不同)

  • 跨域:跨域的安全限制都是对浏览器端来说的,服务器端是不存在跨域安全限制的。浏览器的同源策略限制从一个源加载的文档或脚本与来自另一个源的资源进行交互。

 

axios和ajax及fetch说明

jQuery(ajax), fetch, axios三种前端异步请求的方法, 为了在当前页面下, 异步返回资源.

这三个其实都是用来请求数据的,那他们的区别在哪里呢?其实 axios 和 ajax都是对XMLHttpRequest这个对象的封装;而fetch则是window下的一个方法,是一个更底层的方法。

(注意: 不仅仅是域名不一样, 严格演说, 端口协议和域名, 有一个不一样就是跨域请求, Cross-Origin Resource Sharing这里的Origin有域,协议和端口的意思)

(所以在微服务中, 有时候可能只是端口号不同, 也需要解决跨域问题)

首先, 当我们访问页面资源时, 比如谷歌图片或者百度图片, 有时候希望在当前页面下返回资源, 而不是刷新页面或者跳转. 我们可以发现, 访问谷歌图片点击其中的某一个图片时, 可以在当前页面下通过异步拿到资源. 但是访问百度图片点击图片, 需要跳转页面或者页面重新刷新(2021-11月).

异步请求资源时, 大体可以使用ajax, fetch, axios三种方法.

如今, 很多项目的部署都是通过微服务来部署的. 图片类似的大文件, 为了提高访问的速度, 一般会放在一个单独的微服务下. 比如京东的对象管理系统. (我个人认为, 微服务之间的跨域问题, 因该使用nginx代理更合理, 因为这样可以减少代码上的依赖)

所以, 当我们想要异步请求资源的时候, 有时候会碰到跨域问题. 这时, 我们有三种解决方法.

跨域问题解决方法

1. response header解决方法

在服务器端的响应头加入使用 Origin 和 Access-Control-Allow-Origin 就能完成最简单的访问控制. * 就是任何都可以访问. 我们使用检查来看百度图片时, 就可以看到访问时Network的Headers里, Response Headers的Access-Control-Allow-Origin* , 这里相当于是任何域都可以访问的意思.

2. jsonp解决方法

JSONP是一种非正式传输协议,该协议的一个要点就是允许用户传递一个callback(或者一开始就定义一个回调方法)参数给服务端,然后服务端返回数据时会将这个callback 参数作为函数名来包裹住 JSON 数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。

注意, 我们通过href src所请求下来的, js脚本, css文件, 或者image图片文件, 视频文件, 都不存在跨域问题. 只有通过ajax请求才存在跨域问题.

所以我们又发现,Web页面上调用js文件时则不受是否跨域的影响(不仅如此,我们还发现凡是拥有src这个属性的标签都拥有跨域的能力,比如<script>、<img>、<iframe>);

为了便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP,该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了

总结原生JS实现JSONP的步骤

1 客户端

  1. 定义获取数据后调用的回调函数
  2. 动态生成对服务端JS进行引用的代码
  • 设置url为提供jsonp服务的url地址,并在该url中设置相关callback参数
  • 创建script标签,并设置其src属性
  • 把script标签加入head,此时调用开始。

2 服务端

将客户端发送的callback参数作为函数名来包裹住JSON数据,返回数据至客户端。

JSONP在jQuery中的具体实现

在jQuery中实现JSONP主要有两种方式。

  • $.getJSON
  • $.ajax

AJAX与JSONP的异同:

  1. AJAX和JSONP这两种技术在调用方式上“看起来”很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jQuery和extjs等框架都把JSONP作为AJAX的一种形式进行了封装;
  2. 但AJAX和JSONP其实本质上是不同的东西。AJAX的核心是通过XmlHttpRequest获取非本页内容,而JSONP的核心则是动态添加<script>标签来调用服务器提供的js脚本。
  3. 所以说,其实AJAX与JSONP的区别不在于是否跨域,AJAX通过服务端代理一样可以实现跨域,JSONP本身也不排斥同域的数据的获取。
  4. 还有就是,JSONP是一种方式或者说非强制性协议,如同AJAX一样,它也不一定非要用JSON格式来传递数据,如果你愿意,字符串都行,只不过这样不利于用JSONP提供公开服务。
  5. 总而言之,JSONP不是AJAX的一个特例,哪怕jQuery等巨头把它封装进了AJAX,也不能改变这一点!

我理解, js, css获取不需要设计跨域问题, 所以在src中添加函数方法, 用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了

3. nginx代理解决方法

配置nginx进行反向代理解决跨域

反向代理的原理就是讲前端的地址和后端的地址用nginx转发到同一个地址下,如5500端口和3000端口都转到3003端口下, 也可以解决跨域问题.

```python
class BertPooler(nn.Module):
    def __init__(self, config):
        super().__init__()
        self.dense = nn.Linear(config.hidden_size, config.hidden_size)
        self.activation = nn.Tanh()

    def forward(self, hidden_states):
        # We "pool" the model by simply taking the hidden state corresponding
        # to the first token.
        first_token_tensor = hidden_states[:, 0]
        pooled_output = self.dense(first_token_tensor)
        pooled_output = self.activation(pooled_output)
        return pooled_output
from transformers.models.bert.configuration_bert import *
import torch
config = BertConfig.from_pretrained("bert-base-uncased")
bert_pooler = BertPooler(config=config)
print("input to bert pooler size: {}".format(config.hidden_size))
batch_size = 1
seq_len = 2
hidden_size = 768
x = torch.rand(batch_size, seq_len, hidden_size)
y = bert_pooler(x)
print(y.size())
```

  • 22
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值