【逐点突破系列】 深入跨域

fetch(‘https://photo.sina.cn/aj/index?page=1&cate=recommend’)

.then(data=>{

console.log(data);

})

复制代码

通过 live-server打开浏览器,在控制台可以看到报错了,因为这个是一个跨域的请求:

接下来我们来看看JSONP如何解决这个问题:

[](()3.3.2、jsonp 如何使用?原理是什么?返回数据格式?前端怎么处理?

还是请求上面的这个网站地址,我们把代码改成下面这样:

复制代码

再来看看页面控制台输出:

data成功取到了。但是我们的数据到达之后是json数据,不能直接使用,script标签是一个加载资源的标签,它并不能直接运行这个代码。

事实上我们是在访问的时候,在请求的地址后面加上一个,&callback=callback,通知服务器,本地想进行一个跨资源访问(以JSOP的形式进行跨域)。等号后面的callback是一个你自己定义的函数,名字可自取,这个函数就是,通知我需要请求的地址,这边页面上我有一个函数,它会等待调用,用来执行你发过来的数据(也就是可以去执行把数据请求下来的操作)。

因此在数据到达之后,还包了一层函数 callback({data}),当数据通过script标签请求下来之后,再通过callback实现了一个调用本地资源的能力。

最后再理一下这部分的内容:

《大厂前端面试题解析+Web核心总结学习笔记+企业项目实战源码+最新高清讲解视频》无偿开源 徽信搜索公众号【编程进阶路】

  • JSONP的原理

script标签请求数据,在请求的地址后面加上一个,&callback=callback,请求的服务器就在json数据外面包一层callback函数,当这个带有数据的callback函数可以在script得到之后可以运行的函数:

  • 返回的数据格式

JSON

  • 以及前端如何处理的

JSON with padding — callback({data})

[](()3.3.3、自己封装一个jsonp?

  1. 准备工作

复制代码

  1. 具体实现流程
  • 确定传递参数: url 、携带的参数 、callback;

  • 处理url上的参数(?后面的);

  • 准备好url(携带callback函数);

  • 构建script标签;

  • 把这个标签挂到window上

复制代码

[](()3.3.4、实现一个jsonp服务器端?(node版本,express版本)

[](()node版本

创建一个结构如下的服务器端文件夹,我们将在index.js中实现我们的JSONP:

var http = require(‘http’);

http.createServer(function(req, res){

// req url callback=?

console.log(req.url);

let data = {a: 1};

res.writeHead(200, {‘Content-type’ : ‘text/json’})

const reg = /callback=([\w]+)/

if (reg.test(req.url)) {

let padding = RegExp.$1

res.end(${padding}(${JSON.stringify(data)}))

} else {

res.end(JSON.stringify(data));

}

// res.end(‘

Hello World

’);

res.end(JSON.stringify(data));

}).listen(3000);

复制代码

[](()express 版本

var express = require(‘express’);

var cors = require(‘cors’);//后端cors 中间件

const app = express();

app.use(cors());

app.get(‘/product’,(req,res)=>{

res.json({

a:1,

b:2

})

})

app.listen(8000,()=>{

console.log(‘server is ok’)

})

复制代码

[](()3.4 cors


[](()3.4.1、介绍一下cors?

CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

[](()3.4.2、简单请求和非简单请求?

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。

除了简单请求其他的都是非简单请求,因此只要记住哪些是简单请求就可以啦:

[](()简单请求:(需要同时满足下面两种条件)
  1. 请求方法是以下三种方法之一:
  • HEAD

  • GET

  • POST

  1. HTTP的头信息不超出以下几种字段:
  • Accept:设置接受的内容类型(请求头)

  • Accept-Language:设置接受的语言(请求头)

  • Content-Language:为封闭内容设置自然语言或者目标用户语言(响应头)

  • Content-Type:(设置请求体的MIME类型(适用POST和PUT请求))只限于三个值

application/x-www-form-urlencoded

中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)

multipart/form-data:将表单的数据处理为一条消息,以标签为单元,用分隔符分开。既可以上传键值对,也可以上传文件。

text/plain:text/plain :纯文本格式

[](()3.4.3、项目中怎么使用?

  • 服务器端:

const express = require(‘express’);

const app= express();

app.get(‘/’, (req, res)=>{

console.log(‘server is OK’);

res.end(‘jingjing’)

});

// app.use((req, res, next) => {

// res.header(“Access-Control-Allow-Origin”,‘http://localhost:5500’);

// res.header(“Access-Control-Allow-Credentials”, true);

// res.header(“Access-Control-Allow-Headers”, ‘Content-Type,Content-Length,Authorization, Accept,X-Requested-With’);

// res.header(“Access-Control-Allow-Methods”, ‘PUT,POST,GET,DELETE,OPTIONS,HEAD’);

// req.method === ‘OPTIONS’ ? res.send(‘CURRENT SERVICES SUPPORT CROSS DOMAIN REQUESTS!’) : next();

// });

app.listen(8081, ()=>{

console.log(‘Server is running at http://localhost:8081’)

})

复制代码

  • 前端请求:

sendAjax

复制代码

跨域报错:

把中间注释的部分放开再执行:没有上面的报错了,也返回了

console.log(xhr.responseText);

console.log(‘成功了’)

分析一下:

  • “Access-Control-Allow-Origin”,http://localhost:5500

如果服务端仅允许来自 http://localhost:5500的访问,如果服务端返回的 Access-Control-Allow-Origin: * 表明,该资源可以被任意外域访问。

  • “Access-Control-Allow-Credentials”, true):

Access-Control-Allow-Credentials 头指定了当浏览器的credentials设置为true时是否允许浏览器读取response的内容。

  • “Access-Control-Allow-Headers”, ‘Content-Type,Content-Length,Authorization, Accept,X-Requested-With’):

首部字段 Access-Control-Allow-Headers 表明服务器允许请求中携带字段 X-PINGOTHER 与 Content-Type。

  • “Access-Control-Allow-Methods”, ‘PUT,POST,GET,DELETE,OPTIONS,HEAD’:

首部字段 Access-Control-Allow-Methods 表明服务器允许客户端使用 POST, GET 和 OPTIONS 等方法发起请求

  • req.method === ‘OPTIONS’ ? res.send(‘CURRENT SERVICES SUPPORT CROSS DOMAIN REQUESTS!’) : next():

“需预检的请求”要求必须首先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求(除简单请求以外的,比如 POST方法就需要用到预检)

[](()3.5、代理 (nginx)


[](()3.5.1 原理

A网站向B网站请求1.js文件时,向B网站发送一个获取的请求,nginx根据配置文件接收这个请求,代替A网站向B网站来请求这个资源,nginx拿到这个资源后再返回给a网站,以此来解决了跨域问题。

[](()3.5.2 使用

使用Nginx,有关下载和配置Nginx,我就不再这里说了,感兴趣的小伙伴可以参考一下这篇文章,里面配置相关的讲的比较清楚。[正确的Nginx跨域配置](()

(自己平时也没怎么用就是,唉,大多知识点也是一边写一边理)

但是的但是,学习还是要学滴。回到最开始我们提到的一些问题,来看看你能回答多少 👇👇👇

[](()总结

=====================================================================

最后再来一次拷问:

  1. 能说说跨域吗?

  2. 能说说同源策略吗?

  3. 为什么要同源策略,它限制了什么?

  4. 你知道哪些跨域方案呢?

  5. 有关cookie的跨域怎么实现?

  6. 能具体说说JSONP吗?返回什么数据呢,前端怎么处理呢?知道什么原理吗?实现过吗?JSONP服务器端实现过吗?

  7. postMessage 了解吗?怎么使用?需要注意什么?(安全方面)

  8. 代理了解过吗?用过哪些代理方案呢不?怎么在项目中用呢?

  9. cors可以具体说一个简单请求和非简单请求吗?具体过程说一下?项目中怎么使用?

🙈

[](()最后(相关面试题)

============================================================================

因为有拷问题了,拷问题大家能回答上也是掌握啦,这次的面试题小编就以PDF形式展示给大家,不然篇幅被限制了,面试题出不来啦,需要前端面试题完整版PDF的,[点击这里直接领取](():

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值