全解跨域请求处理办法,mysql高频面试题

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Web前端全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024c (备注前端)
img

正文

我们试想一下以下几种情况:

  1. 我们打开了一个天猫并且登录了自己的账号,这时我们再打开一个天猫的商品,我们不需要再进行一次登录就可以直接购买商品,因为这两个网页是同源的,可以共享登录相关的 cookie 或 localStorage 数据;

  2. 如果你正在用支付宝或者网银,同时打开了一个不知名的网页,如果这个网页可以访问你支付宝或者网银页面的信息,就会产生严重的安全的问题。如果该未知网站是黑客的工具,那他就可以借此发起 CSRF 攻击了。显然浏览器不允许这样的事情发生;

  3. 想必你也有过同时登陆好几个 qq 账号的情况,如果同时打开各自的 qq 空间浏览器会有一个小号模式,也就是另外再打开一个窗口专门用来打开第二个 qq 账号的空间。

为了解决不同域名相互访问数据导致的不安全问题,Netscape提出的一个著名的安全策略——同源策略,它是指同一个“源头”的数据可以自由访问,但不同源的数据相互之间都不能访问。

同源策略

很明显,上述第1个和第3个例子中,不同的天猫商店和 qq 空间属于同源,可以共享登录信息。qq 为了区别不同的 qq 的登录信息,重新打开了一个窗口,因为浏览器的不同窗口是不能共享信息的。而第2个例子中的支付宝、网银、不知名网站之间是非同源的,所以彼此之间无法访问信息,如果你执意想请求数据,会提示异常:

No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘null’ is therefore not allowed access.

那么什么是同源的请求呢?同源请求要求被请求资源页面和发出请求页面满足3个相同:

协议相同

host相同

端口相同

简单理解一下:

/以下两个数据非同源,因为协议不同/

http://www.abc123.com.cn/item/a.js

https://www.abc123.com.cn/item/a.js

/以下两个数据非同源,因为域名不同/

http://www.abc123.com.cn/item/a.js

http://www.abc123.com/item/a.js

/以下两个数据非同源,因为主机名不同/

http://www.abc123.com.cn/item/a.js

http://item.abc123.com.cn/item/a.js

/以下两个数据非同源,因为协议不同/

http://www.abc123.com.cn/item/a.js

http://www.abc123.com.cn:8080/item/a.js

/* 以下两个数据非同源,域名和 ip 视为不同源

  • 这里应注意,ip和域名替换一样不是同源的

  • 假设www.abc123.com.cn解析后的 ip 是 195.155.200.134

*/

http://www.abc123.com.cn/

http://195.155.200.134/

/以下两个数据同源/ /* 这个是同源的*/

http://www.abc123.com.cn/source/a.html

http://www.abc123.com.cn/item/b.js

HTTP 简单请求和非简单请求

http 请求满足一下条件时称为简单请求,否则是非简单请求:

  1. 请求方法是 HEAD,GET,POST 之一

  2. HTTP的头信息不超出以下几种字段:

  • Accept

  • Accept-Language

  • Content-Language

  • Last-Event-ID

  • Content-Type

  1. Content-Type 取值仅限于 application/x-www-form-urlencoded, multipart/form-data, text/plain

非简单请求在发送之前会发送一次 OPTION 预请求,如果在跨域操作遇到返回 405(Method Not Allowed) 错误,需要服务端允许 OPTION 请求。

HTTP 跨域访问的处理办法及适用条件

JSOP

适用条件:请求的 GET 接口需要支持 jsonp 访问

这里需要强调的是,jsonp 不属于 Ajax 的部分,它只是把 url 放入 script 标签中实现的数据传输,不受同源策略限制。由于一般库也会把它和 Ajax 封装在一起,由于其和 Ajax 根部不是一回事,所以这里不讨论。下面是一个 jsonp 的例子:

window.jsonpCallback = console.log;

var JSONP = document.createElement(“script”);

JSONP.src = “http://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=13122222222&t=” + Math.random() + “&callback=jsonpCallback”;;

document.body.appendChild(JSONP);

后端支持jsonp方式(Nodejs)

var querystring = require(‘querystring’);

var http = require(‘http’);

var server = http.createServer();

server.on(‘request’, function(req, res) {

var params = qs.parse(req.url.split(‘?’)[1]);

var fn = params.callback;

// jsonp返回设置

res.writeHead(200, { ‘Content-Type’: ‘text/javascript’ });

res.write(fn + ‘(’ + JSON.stringify(params) + ‘)’);

res.end();

});

server.listen(‘8080’);

console.log(‘Server is running at port 8080…’);

document.domain

适用条件: host 中仅服务器不同的情况,域名本身应该相同

www.dom.comw1.dom.com 需要同源才能访问,可以将 document.domain 设置为 dom.com 解决该问题

document.domain = ‘dom.com’;

例如,我想开发一个浏览器插件,发现腾讯视频页有个 iframe 其本身的跨域的,无法获取其 iframe 的 DOM 对象。但域名部分相同,可以通过该方法解决.

注:如果你想设置它为完全不同的域名,那肯定会报同源错误的,注意使用范围!

嵌入 iframe

适用条件: host 中仅服务器不同的情况,域名本身应该相同

有了上面的例子就不难理解这个方法了,严格来说这不是一个新的方法,而是上一个方法的延伸。通过设置document.domain, 使同一个域名下不同服务器名的页面可以访问数据,但值得注意的是:这个数据访问不是相互的,外部页面可以访问 iframe 内部的数据,但 iframe 无法不能访问外部的数据。

location.hash

适用条件:iframe 和其宿主页面通信

一个完成的 url 中 # 及后面的部分为 hash, 可以通过修改这个部分完成iframe 的和宿主直接的数据传递,下面演示一下 iframe 页面(B.html)像宿主(A.html)传数据, 反之同理:

// A.html

data = [‘book’, ‘map’, ‘shelf’, ‘knife’];

setTimeout(() => {

location.hash = window.encodeURIComponent(data.join(‘/’));

}, 1000);

// B.html

window.parent.onhashchange = function (e) {

var data = window.decodeURIComponent(e.newURL.split(‘#’)[1]).split(‘/’);

console.log(data); // [“book”, “map”, “shelf”, “knife”]

}

*注意反向传递数据时应该使用 window.parent.location.hash

window.name

适用条件:宿主页面和 iframe 之间通信

window对象有个name属性,该属性有个特征:即在 window 的生命周期内,窗口载入的所有的页面 (iframe) 都是共享一个 window.name 的,每个页面对 window.name 都有读写的权限,window.name 是持久存在一个窗口载入过的所有页面中的,并不会因新页面的载入而进行重置。

这样在 window 中编辑 window.name 就可以在 iframe 中得到,但这个过程缺乏监听,宿主页面(A.html)和 iframe 页面(B.html)相互并不知道对方在什么时候修改该值:

// A.html

setTimeout(() => {

window.parent.name = “what!”;

}, 2000);

// B.html

setTimeout(() => {

console.log(window.name); // what!

}, 2500);

postMessage

适用条件:postMessage 是 H5 提出的一个消息互通的机制,解决 iframe 不能消息互通的问题,也可以跨 window 通信,语法如下:

// 在 www.siteA.com 中发出消息

// @message{any} 要发送的数据(注意:老版本浏览器只支持字符串类型)

// @targetOrigin{string} 规定接收数据的域,只有其指定的域才能收到消息,如果为"*"则没用域的限制

// transfer{any} 与 message 一同发送并转移所有权

window.postMessage(message, targetOrigin, [transfer]);

// 在另一个页面接受参数

window.onmessage = console.log;

这里暂不谈论第三个参数,因为你可能一辈子也用不到它。而 targetOrigin 最好不要使用 “*”,除非你想让所有页面都收到你的消息。

一种你会用到的场景(iframe):

<!-- www.siteA.com/index.html --> <script> window.addEventListener('message', function(e){ console.log('Get message: "' + e.data.title + '" from ' + e.origin); // 'Get message: "Saying hello to siteA!" from http://www.siteB.com' }); </script> <iframe src="http://www.siteB.com"></iframe> <!-- www.siteB.com/index.html --> <script> function sendMessage(){ window.postMessage({title: 'Saying hello to siteA!'}, 'http://www.siteA.com'); } setTimeout(sendMessage, 2000); </script>

这一种仅仅是没有了iframe,当你在同一个浏览器窗口同时打开 www.siteA.comwww.siteB.com 两个标签时也可以这样用

<!-- www.siteA.com/index.html --> <script> window.addEventListener('message', function(e){ console.log('Get message: "' + e.data.title + '" from ' + e.origin); // 'Get message: "Saying hello to siteA!" from http://www.siteB.com' }); </script> <!-- www.siteB.com/index.html --> <script> function sendMessage(){ window.postMessage({title: 'Saying hello to siteA!'}, 'http://www.siteA.com'); } setTimeout(sendMessage, 2000); </script>

反向代理服务器

页面需要访问一些跨域接口,由于代理的存在,在服务器看来请求是不跨域,所以使用各种请求。但需要注意 http 到 https 的兼容问题。

比如当我在一些在线平台开发网站后得到一个页面 www.site-A.com, 而这个页面需要请求我自己的数据服务器data.site-B.com上的数据, 这样同样会产生跨域问题,但是www.site-A.com这个页面是挂在第三方服务器上的,解决这个问题可以采用代理服务器的方法:

var express = require(‘express’);

var request = require(‘request’);

var app = express();

app.use(‘/api’, function(req, res) {

var url = ‘http://data.site-B.com/api2’ + req.url;

req.pipe(request(url)).pipe(res);

});

app.use(‘/’, function(req, res) {

var url = ‘http://data.site-C.com’;

req.pipe(request(url)).pipe(res);

});

当然还需要同时配置一个 host:

127.0.0.1 local.www.site-B.com

然后访问 local.www.site-B.com 就 OK 了。

CORS

适用条件:CORS 需要服务端支持,且存在一定的兼容性问题(如今你已经可以不考虑,但必要时不要忘了这个’bug’)。其通过添加 http 头关键字实现跨域可访问,包括如下头内容:

www.siteA.com/api 返回相应需要具有如下 http 头字段

Access-Control-Allow-Origin: ‘http://www.siteB.com’ # 指定域可以请求,通配符’*'(必须)

Access-Control-Allow-Methods: ‘GET,PUT,POST,DELETE’ # 指定允许的跨域请求方式(必须)

对象篇

模块化编程-自研模块加载器

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
GxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy82MTY4MzU2LWUyNWEzOGRhNTU1NTBmOGY?x-oss-process=image/format,png)

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
[外链图片转存中…(img-GH82TimQ-1713466097836)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值