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?
- 准备工作
复制代码
- 具体实现流程
-
确定传递参数: 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)。
除了简单请求其他的都是非简单请求,因此只要记住哪些是简单请求就可以啦:
[](()简单请求:(需要同时满足下面两种条件)
- 请求方法是以下三种方法之一:
-
HEAD
-
GET
-
POST
- 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跨域配置](()
(自己平时也没怎么用就是,唉,大多知识点也是一边写一边理)
但是的但是,学习还是要学滴。回到最开始我们提到的一些问题,来看看你能回答多少 👇👇👇
[](()总结
=====================================================================
最后再来一次拷问:
-
能说说跨域吗?
-
能说说同源策略吗?
-
为什么要同源策略,它限制了什么?
-
你知道哪些跨域方案呢?
-
有关cookie的跨域怎么实现?
-
能具体说说JSONP吗?返回什么数据呢,前端怎么处理呢?知道什么原理吗?实现过吗?JSONP服务器端实现过吗?
-
postMessage 了解吗?怎么使用?需要注意什么?(安全方面)
-
代理了解过吗?用过哪些代理方案呢不?怎么在项目中用呢?
-
cors可以具体说一个简单请求和非简单请求吗?具体过程说一下?项目中怎么使用?
🙈
[](()最后(相关面试题)
============================================================================
因为有拷问题了,拷问题大家能回答上也是掌握啦,这次的面试题小编就以PDF形式展示给大家,不然篇幅被限制了,面试题出不来啦,需要前端面试题完整版PDF的,[点击这里直接领取](():