当前位置:网站首页>解决跨域
解决跨域
2022-06-28 02:48:00 【weixin_47164846】
.解决跨域的方式
几种主流的跨域解决方案
1.JSONP处理跨域
- 原理:
jsonp是一种跨域通信的手段,它的原理其实很简单:
a:首先是利用script标签的src属性来实现跨域。
b:通过将前端方法作为参数传递到服务器端,然后由服务器端注入参数之后再返回,实现服务器端向客户端通信。
c: 由于使用script标签的src属性,因此只支持get方法
2.实现方式:
//创建script标签
function createScript(){
//定义一个script标签
let oScript = document.createElement("script");
//script的src属性 直接赋值为需要跨域的接口链接
//并且定义callback参数,后面跟一个回调函数
oScript.src = `https://api.asilu.com/today?callback=getTodays`;
//将生成的script追加到我们的dom中
document.body.appendChild(oScript);
}
12345678910
//callback对于的函数
function getTodays(data) {
//获取跨域得到的对象数据
let oTodays = data.data;
}
上述就是通过jsonp 实现了一个跨域请求,获取天气的数据.既然叫jsonp,显然目的还是json,而且是跨域获取,利用js创建一个script标签,把json的url赋给script的scr属性,把这个script插入到页面里,让浏览器去跨域获取资源,callback是页面存在的回调方法,参数就是想得到的json,回调方法要遵从服务端的约定一般是用 callback 或者 cb,特别注意的是jsonp只针对get形式的请求
3.优缺点
优点:使用简便,没有兼容性问题。
缺点:
只支持 GET 请求。
前后端需要配合。
由于是从其它域中加载代码执行,因此如果其他域不安全,很可能会在响应中夹带一些恶意代码。
2.CORS跨域资源共享(xhr2)
1.原理
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)- 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制- 整个CORS通信过程,都是浏览器自动完成,不需要用户参与- 对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样- 实现CORS通信的关键是服务端,只要服务端实现了CORS接口,就可以跨源通信
2.实现
实现CORS并不难,只需服务端做一些设置即可:如
// 控制允许的请求来源
header("Access-Control-Allow-Origin:*"); // *表示允许任何来源 基本上设置这个就可以了
//另外,还有一些需要设置put请求 delete请求的,还有自定义请求头,nodejs默认是get,post
// 控制允许的自定义请求头
'Access-Control-Allow-Headers': 'abc,efg',
// 控制允许的请求方式
'Access-Control-Allow-Methods': 'GET,POST,PUT,PATCH,DELETE'
注意:IE10以下不支持CORS
3.优缺点
优点:
CORS 通信与同源的 AJAX 通信没有差别,代码完全一样,容易维护。
支持所有类型的 HTTP 请求。
缺点
存在兼容性问题,特别是 IE10 以下的浏览器。
第一次发送非简单请求时会多一次请求。
3.服务器代理跨域
1.原理:
通过服务端语言代理请求。如PHP,C# 服务端语言是没有跨域限制的。- 让服务器去别的网站获取内容然后返回页面。因为同源策略是针对浏览器的安全性限制.服务器不存在跨域问题,所以可以由服务器请求所要域的资源再返回给客户端。
我们在请求第三方的数据时,通过浏览器的ajax请求肯定是不行的,因为人家也不会给你设置cors,所以我们这边的服务器代理解决跨域的方式就应运而生了.
2.实现
我这边通过nodejs+express实现服务代理跨域
需要安装中间件 http-proxy-middleware
$ npm install http-proxy-middle
服务端代码
// 通过代理解决跨域问题
/** * 使用nodejs启动一个代理服务 * 第三方的 http-proxy-middleware 中间件 */
//引入express
const express = require('express');
//引入代理中间件
const {
createProxyMiddleware } = require('http-proxy-middleware');
//声明express实例
const app = express();
// 注册一个cors的中间件,允许跨域
app.use((req, res, next) => {
res.set({
//允许所有域请求,实际开发中,*需要改成对应的域名
'Access-Control-Allow-Origin': '*',
// 设置允许前端传递的那些自定义请求头
'Access-Control-Allow-Headers': 'token',
// 设置允许的请求方式
'Access-Control-Allow-Methods': 'GET,POST,PUT,PATCH,DELETE'
});
//必须要写,将控制权交给下一个
next();
});
// 注册一个代理中间件
// 前端服务:http://localhost:8080
// 代理服务:http://localhost:3000
// 目标服务:http://m.maoyan.com
app.use('/api', createProxyMiddleware({
//配置选项
// 目标地址:只需要协议和主机
target: "http://m.maoyan.com",
/** * 路径重写 * * 当我们通过代理访问目标接口的流程大致如下 * http://localhost:8080 -> 请求 -> * http://localhost:3000/api/ajax/movieOnInfoList -> 代理到 -> * http://m.maoyan.com/api/ajax/movieOnInfoList * 这时真实的目标接口地址是没有 /api 这个前缀的。所以会导致请求失败 404 等问题 * * 设置如下的路径重写规则之后,流程如下 * http://localhost:8080 -> 请求 -> * http://localhost:3000/api/ajax/movieOnInfoList -> 代理到 -> * http://m.maoyan.com/ajax/movieOnInfoList */
pathRewrite: {
"^/api": ""
},
// 虚拟托管站点所需, 一般直接设置为true就好
changeOrigin: true
}));
//监听3000端口,启动服务
app.listen(3000, () => {
console.log("代理服务启动成功");
});
前端代码
<script>
$(function () {
$.ajax({
url: 'http://localhost:3000/api/ajax/movieOnInfoList',
type: 'GET',
success: function (res) {
console.log(res)
}
})
})
</script>
边栏推荐
- Li Kou daily question - day 29 -523 Count odd numbers in interval range
- 栈的基本操作(C语言实现)
- Self use tool unity video player that monkeys can use
- 开口式霍尔电流传感器如何助力直流配电改造?
- 可扩展数据库(上)
- SSH框架的搭建(上)
- Win 10出现bitlocke恢复,蓝屏错误代码0x1600007e
- WARN:&nbsp;SQL&nbsp;Error:&nbsp;…
- 17 `bs对象.节点名h3.parent` parents 获取父节点 祖先节点
- Scalable storage system (I)
猜你喜欢
随机推荐
Go 數據類型篇(四)之浮點型與複數類型
Ten years' experience of Software Engineer
nn. Parameter and torch nn. Init series of functions to initialize model parameters
MySQL错误
Online DDL implementation mechanism in InnoDB of database Series
Go speed
资源管理、高可用与自动化(中)
Tardigrade: Trino's solution to ETL scenarios
劲爆!YOLOv6又快又准的目标检测框架开源啦(附源代码下载)
数据库
Import an excel file, solve the problem of skipping blank cells without reading and moving the subscript forward, and return_ BLANK_ AS_ Null red
在牛客中使用JS编程题【split】
Arm development studio build compilation error
【PaddleDetection】ModuleNotFoundError: No module named ‘paddle‘
Scalable storage system (I)
可扩展数据库(上)
mysql获取当前时间是一年的第多少天
资源管理、高可用与自动化(下)
Why is the service implementation class always red
可扩展存储系统(上)









