6-JS的Fetch 跨域问题

2023-11-15

跨域访问
在这里插入图片描述

  • 只要协议、主机、端口之一不同,就不同源,例如
    • http://localhost:7070/a 和 https://localhost:7070/b 就不同源
  • 同源检查是浏览器的行为,而且只针对 fetch、xhr 请求
    • 如果是其它客户端,例如 java http client,postman,它们是不做同源检查的
    • 通过表单提交、浏览器直接输入 url 地址这些方式发送的请求,也不会做同源检查
  • 更多相关知识请参考

请求响应头方式
在这里插入图片描述

  • fetch 请求跨域,会携带一个 Origin 头,代表【发请求的资源源自何处】,目标通过它就能辨别是否发生跨域
    • 我们的例子中:student.html 发送 fetch 请求,告诉 tomcat,我源自 localhost:7070
  • 目标资源通过返回 Access-Control-Allow-Origin 头,告诉浏览器【允许哪些源使用此响应】
    • 我们的例子中:tomcat 返回 fetch 响应,告诉浏览器,这个响应允许源自 localhost:7070 的资源使用
      实例:
      请求方:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style scoped>
        div {
            font-family: 华文行楷;
            font-size: 20px;
        }
    
        .title {
            margin-bottom: 10px;
            font-size: 30px;
            color: #333;
            text-align: center;
        }
    
        .row {
            background-color: #fff;
            display: flex;
            justify-content: center;
        }
    
        .col {
            border: 1px solid #f0f0f0;
            width: 15%;
            height: 35px;
            text-align: center;
            line-height: 35px;
        }
    
        .bold .col {
            background-color: #f1f1f1;
        }
    </style>
</head>
<body>
    <div>
        <div class="title">学生列表</div>
        <div class="thead">
            <div class="row bold">
                <div class="col">编号</div>
                <div class="col">姓名</div>
                <div class="col">性别</div>
                <div class="col">年龄</div>
            </div>
        </div>
        <div class="tbody">
        </div>
    </div>
    
    <template id="tp">
        <div class="row">
            <div class="col">xx</div>
            <div class="col">xx</div>
            <div class="col">xx</div>
            <div class="col">xx</div>
        </div>
    </template>
    <script>
        // **访问Tomcat地址存在跨域问题(不同源)**
        fetch("http://localhost:8080/api/students")
        .then(response=>response.json())
        .then(students=>{
            const tp=document.querySelector("#tp");
            const row=tp.content;
            const [r1,r2,r3,r4]=row.querySelectorAll(".col");
        
            
            const tbody=document.querySelector(".tbody");
            for (const {id,name,sex,age} of students){
                r1.textContent=id;
                r2.textContent=name;
                r3.textContent=sex;
                r4.textContent=age;
                //复制元素
                const newRow=document.importNode(row,true)
                //插入节点
                tbody.appendChild(newRow);
            }
        }).catch((e)=>{console.log(e)});
        
      
    </script>
</body>
</html>

Tomcat响应方:

package com.qwy.controller;

import com.inspur.bean.Users;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Controller
public class HelloController {
    @RequestMapping("/api/students")
    //解决不同源跨域访问问题
    @CrossOrigin("http://localhost:7070")
    @ResponseBody
    public List<Users> getMessage() {

        Users users1 = new Users(1, "刘备", "男", 12);
        Users users2 = new Users(2, "张非", "男", 12);
        Users users3 = new Users(3, "关羽", "女", 12);
        Users users4 = new Users(4, "刘邦", "男", 12);
        Users users5 = new Users(5, "诸葛", "女", 12);
        Users users6 = new Users(6, "刘备", "男", 12);
        Users users7 = new Users(7, "张非", "男", 12);
        Users users8 = new Users(8, "关羽", "女", 12);
        Users users9 = new Users(9, "刘邦", "男", 12);
        Users users10 = new Users(10, "诸葛", "女", 12);
        List<Users> usersList = new ArrayList<Users>();
        Collections.addAll(usersList, users1, users2, users3, users4, users5, users6, users7, users8, users9, users10);

        return usersList;
    }
}

代理方式
在这里插入图片描述

npm install http-proxy-middleware --save-dev

在 express 服务器启动代码中加入

import {createProxyMiddleware} from 'http-proxy-middleware'

// ...

app.use('/api', createProxyMiddleware({ target: 'http://localhost:8080', changeOrigin: true }));

fetch 代码改为

const resp = await fetch('http://localhost:7070/api/students')

const resp = await fetch('/api/students')

实例:
前端服务器express 服务器启动代码中(main.js):

import express from 'express'
import {createProxyMiddleware} from 'http-proxy-middleware'
const app = express()
//代理实现跨域问题解决(以/api开头的地址代理访问http://localhost:8080)
app.use('/api', createProxyMiddleware({ target: 'http://localhost:8080', changeOrigin: true }))
// 添加静态资源的目录
app.use(express.static('./'))
app.listen(7070)

前端页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style scoped>
        div {
            font-family: 华文行楷;
            font-size: 20px;
        }
    
        .title {
            margin-bottom: 10px;
            font-size: 30px;
            color: #333;
            text-align: center;
        }
    
        .row {
            background-color: #fff;
            display: flex;
            justify-content: center;
        }
    
        .col {
            border: 1px solid #f0f0f0;
            width: 15%;
            height: 35px;
            text-align: center;
            line-height: 35px;
        }
    
        .bold .col {
            background-color: #f1f1f1;
        }
    </style>
</head>
<body>
    <div>
        <div class="title">学生列表</div>
        <div class="thead">
            <div class="row bold">
                <div class="col">编号</div>
                <div class="col">姓名</div>
                <div class="col">性别</div>
                <div class="col">年龄</div>
            </div>
        </div>
        <div class="tbody">
        </div>
    </div>
    
    <template id="tp">
        <div class="row">
            <div class="col">xx</div>
            <div class="col">xx</div>
            <div class="col">xx</div>
            <div class="col">xx</div>
        </div>
    </template>
    <script>
        // 访问Tomcat地址存在跨域问题(不同源)
        fetch("http://localhost:7070/api/students")
        .then(response=>response.json())
        .then(students=>{
            const tp=document.querySelector("#tp");
            const row=tp.content;
            const [r1,r2,r3,r4]=row.querySelectorAll(".col");
        
            
            const tbody=document.querySelector(".tbody");
            for (const {id,name,sex,age} of students){
                r1.textContent=id;
                r2.textContent=name;
                r3.textContent=sex;
                r4.textContent=age;
                //复制元素
                const newRow=document.importNode(row,true)
                //插入节点
                tbody.appendChild(newRow);
            }
        }).catch((e)=>{console.log(e)});
        
      
    </script>
</body>
</html>

后端:

package com.qwy.controller;

import com.inspur.bean.Users;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Controller
public class HelloController {
    @RequestMapping("/api/students")
    //解决不同源跨域访问问题
   // @CrossOrigin("http://localhost:7070")
    @ResponseBody
    public List<Users> getMessage() {

        Users users1 = new Users(1, "刘备", "男", 12);
        Users users2 = new Users(2, "张非", "男", 12);
        Users users3 = new Users(3, "关羽", "女", 12);
        Users users4 = new Users(4, "刘邦", "男", 12);
        Users users5 = new Users(5, "诸葛", "女", 12);
        Users users6 = new Users(6, "刘备", "男", 12);
        Users users7 = new Users(7, "张非", "男", 12);
        Users users8 = new Users(8, "关羽", "女", 12);
        Users users9 = new Users(9, "刘邦", "男", 12);
        Users users10 = new Users(10, "诸葛", "女", 12);
        List<Users> usersList = new ArrayList<Users>();
        Collections.addAll(usersList, users1, users2, users3, users4, users5, users6, users7, users8, users9, users10);

        return usersList;
    }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

6-JS的Fetch 跨域问题 的相关文章

  • 在 Three.js 中绕点旋转对象的正确方法是什么?

    关于 Three js 的大多数教程 问题都建议使用 Three js 绕点旋转对象的方法是在要旋转的位置创建父对象 附加对象 然后移动子对象 然后 当父级旋转时 子级围绕该点旋转 例如 Make a pivot var pivot new
  • 如何删除除任何特定 id 之外的元素

    假设有一个父 id 其中包含许多元素 我想删除除一个元素之外的所有元素 ex parent id children not id n remove
  • JavaScript 添加布尔值

    console log true true 2 console log typeof true true number console log isNaN true true false 为什么两个布尔类型相加会产生一个数字 我有点理解 如
  • 位置特征检测:固定

    我正在尝试找到一个脚本来检测设备是否放置position fixed元素相对于视口而不是整个文档 目前 标准桌面浏览器和 Mobile Safari 适用于 iOS 5 都是这样做的 而 Android 设备则相对于整个文档放置固定元素 我
  • 使用 Angular 指令禁用文本选择

    我正在学习 JavaScript 和 AngularJS 我想使用 Angular Directive 禁用文本选择 我有该函数的 JavaScript 代码 function clearSelection if document sele
  • 使用 Node.js 构建网站的最佳实践

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 我想知道如何使用 Node js 从头开始 开发一个网站 我明白我怎么能possibly
  • 在版本 4.4.6 中禁用 ckeditor 上下文菜单

    我在 Rails4 项目中使用 ckeditor 我尝试了 ckeditor gem 和 ckeditor rails gem 来提供 ckeditor 库 这里有多个帖子 人们希望删除 ckeditor 上下文菜单 以便可以显示本机浏览器
  • 为什么 window 与 Internet Explorer 中的 window.self 不同?

    关于我如何遇到这个问题有一个复杂的背景故事 但为什么self属性不完全等于窗口本身 在 Safari 和 Firefox 及其朋友中 结果如我所料 gt window window self true gt window window se
  • 通过 JavaScript 获取表单名称

    我有一个简单的问题 但我在网上找不到好的解决方案 我有这个 HTML 代码
  • 如何使用javascript确保元素仅在圆上朝一个方向移动?

    好吧 我承认我对三角学真的很糟糕 出于上下文的考虑 我将添加我在这里提到的问题中的内容 参考问题 https stackoverflow com a 39429290 168492 https stackoverflow com a 394
  • React autoFocus 将光标设置为输入值的开头

    我有一个受控输入 最初显示一个值 我已将该输入设置为自动聚焦 但当我希望它出现在末尾时 光标出现在输入的开头 我知道这可能是因为自动对焦是在值之前添加的 但我不能 100 确定 在输入字段末尾完成光标初始化的最佳方法是什么 var Test
  • 如何通过单击链接来更改 div 的内容?

    这是我的网页的 修改后的 jsfiddle 它还有很多 而且定位是正确的 与此相反 http jsfiddle net ry0tec3p 1 http jsfiddle net ry0tec3p 1 a href class btn1 st
  • JavaScript推送函数中的动态变量

    我在 JavaScript 中使用推送功能 var chartData for var i 0 i lt 3 i chartData push date new Date year s mon s date s hr s min s sec
  • 如何使用 Javascript 设置查询字符串

    有没有办法使用 javascript 设置查询字符串的值 我的页面有一个过滤器列表 单击该列表时 它将更改右侧的页内结果窗格 我正在尝试更新 url 的查询字符串值 因此如果用户离开页面 然后单击 后退 按钮 他们将返回到最后一个过滤器选择
  • 使用 JavaScript 移动页面上的按钮

    我的按钮可以移动 但奇怪的是 我无法弄清楚偏移是否有问题 我希望我的按钮随着鼠标光标移动 但现在它的移动方式不是我想要的 有时它会消失 另外 创建的新按钮是重叠的 我不知道如何解决这个问题并拥有更好的外观 var coorA var coo
  • 改变 JavaScript 中的顶部填充

    以下是我在 css 中设置顶部填充的方法 body font size font size px margin 0 padding 100px 0 20px 0 width 100 important 如何使用最简单的 javascript
  • 用于选择特定 div 中具有特定类的锚元素的 jQuery 选择器是什么

    我有一些这样的代码 我想选择每个 a 带有类的标签status在 div 中foo div a class status a div 你可以这样做 foo find status a
  • Highcharts jQuery 渲染问题 - 所有浏览器

    我在尝试使用构建堆积柱形图时遇到了一个奇怪的问题高图表 http www highcharts com 当图表呈现时 在您调整浏览器大小之前 不会显示列无论如何 导致图表重绘 我认为 图表的其余部分显示 轴 标题等 但不显示列本身 我在 I
  • 使用 Enzyme 测试 `React.createRef` api

    我想测试下面的类 它使用React createRef api 不过 快速搜索并没有发现任何这样做的例子 有人成功过吗 我该如何嘲笑裁判 理想情况下我想使用shallow class Main extends React Component
  • 测量窗口偏移

    有没有一种方法可以测量 jQuery 中窗口的偏移量 以便我可以比较 固定 元素和相对定位元素的位置 我需要能够知道窗口滚动了多远 以便我可以使用该图来计算固定元素的高度 相对于视口顶部 和相对对象的高度 相对于顶部 之间的差异文件的内容

随机推荐

  • 浅谈Python网络爬虫应对反爬虫的技术对抗

    在当今信息时代 数据是非常宝贵的资源 而作为一名专业的 Python 网络爬虫程序猿 在进行网页数据采集时经常会遭遇到各种针对爬虫行为的阻碍和限制 这就需要我们掌握一些应对反爬机制的技术手段 本文将从不同层面介绍如何使用 Python 进行
  • 概率论与数理统计学习笔记——第三十讲——方差定义和计算公式

    1 方差概念的引入 2 方差 标准差 均方差 的定义及计算公式 3 0 1分布的方差 4 泊松分布的方差 5 均匀分布的方差 6 指数分布的方差 7 方差的应用实例 投资方案评估
  • Kubernetes Configmap + Secret

    Secret是什么 在Kubernetes中 Secret是一种用于存储敏感信息的资源对象 它主要用于保存密码 API令牌 密钥和其他敏感数据 以供容器 Pod或集群中的其他资源使用 Secret有以下特点 安全存储 Secret对象被用于
  • Eclipse 搭建一个servlet小程序

    跳转 http www importnew com 14621 html Servlet 是一些遵从Java Servlet API的Java类 这些Java类可以响应请求 尽管Servlet可以响应任意类型的请求 但是它们使用最广泛的是响
  • C++中break与continue的用法

    根据break的用法 是在循环体内 强行结束循环的执行 也就是结束整个循环的过程 不再执行循环的条件是否成立 直接转向循环语句下面的语句 continue的作用 在循环语句中 跳出本次循环中余下尚未执行的语句 继续执行下一次循环 其包括两点
  • sqli-labs 1——20关攻略

    1 10 GET传输 Less 1联合查询 优点 查询方便 速度很快 缺点 必须要有显示位 1 判断sql语句中一共返回了多少列 order by 3 对比如下两张图的显示页面 得知有3列 2 查看显示位 union select 1 2
  • 你在用什么写用例

    这段时间用例评审项目组三个成员 有用excel的 有用xmind的 有用禅道的 而我关于用例用到xmind 后来用excel 后来用禅道一直到现在 xmind是思路分析和整理的工具 在最开始做测试的前3年可以说很依赖这款工具 后来 如果要做
  • QT的学习

    1 Test brower 文本浏览器 2 菜单栏窗体里面有预览功能 3 窗口的布局 4 信号与槽 其实就是时间处理函数 类的成员函数 2019 5 27 学习了 QFileDialog 类 就是选择文件 并且把文件名显示到line edi
  • 编写软件测试文档实验报告,黑盒测试软件测试实验报告.doc

    黑盒测试软件测试实验报告 doc 软件测试与质量课程实验报告 实验2 实验2 黑盒测试法实验 姓名院系 学号 任课教师 实验指导教师 实验地点 实验吋间 实验目的 系统地学习和理解黑盒测试的 本概念 原理 熟悉和掌握等价类划分法 边界值分析
  • bootstrap 动态添加js 页面渲染_给Shopify页面添加动态背景特效教程(傻瓜式操作模板)...

    第一种特效 多彩动态气泡向中心焦点聚合js动画 操作 复制代码如下代码 然后打开页面 切换到添加代码模式 然后复制到内容的最顶部 如下图所示
  • 【STM32技巧】使用STM32 HAL库的硬件I2C驱动RX8025T实时时钟芯片

    基础配置 使用单片机APM32F103RBT6 使用外设I2C1 PB7 SDA 使用外设I2C1 PB6 SCK STM32CUBEMX 版本5 6 配置如下 i2c c文件 File Name I2C c Description Thi
  • 目标检测中图片预处理之图片大小分析

    前言 很多做目标检测的新手 拿到数据集就迫不及待想找一个算法来跑它 内心先爽一把 包括我在内也是这样 其实样的做法不合理 我们应该先对数据集进行一些分析 找出数据集的特点 有针对性的进行检测 首先要关注的是图片大小 这个相当重要 假设测试文
  • 01Nginx源码分析之初探Nginx架构

    01Nginx源码分析之初探Nginx架构 注 接下来的源码分析我都是参考以下这位博主的 但是有些地方不对的我会修改 毕竟每个人理解不一样 并且版本为nginx stable 1 18 自娱自乐的代码人 1 初探Nginx架构 第一篇没什么
  • 深度学习之手写数字识别

    当我们开始学习编程的时候 第一件事往往是学习打印 Hello World 就好比编程入门有Hello World 机器学习入门有MNIST MNIST是一个入门级的计算机视觉数据集 它包含各种手写数字图片 它也包含每一张图片对应的标签 告诉
  • 【Python爬虫】urllib模块,User-agent

    通过 rullib模块 爬取html内容 文章目录 1 urllib模块分类 2 方法使用案例 3 重构User Agent 1 urllib模块分类 urllib request 请求模块 用于打开和读取 URL urllib error
  • 《宫本武藏》

    吉川英治 宫本武藏 地之卷 水之卷 火之卷 风之卷 http book sina com cn nzt his gongbenwuzang 空 二天之卷 http lianzai book qq com book 3746 缺少最后的 圆明
  • RealityCapture场景建模笔记

    Unity Photogrammetry Workflow 5 2 8 着色和贴纹理 Colorize or Texture 5 2 10 网格输出 Mesh export 输出附有颜色信息的Mesh 点云 5 2 8 着色和贴纹理 Col
  • kvm内存管理

    qemu kvm 进程很像一个普通的linux程序 它通过通常的malloc和mmap调用来申请内存 如果一个客户系统想使用1G物理内存 qemu kvm将会做一个malloc 1 lt lt 30 调用 在主机上申请1G的虚拟地址 然而
  • 固定阈值threshold Expected cv::UMat for argument 'mat'

    出错的原因是左边少了一个变量名 你的写法可能是这样 正确的应该是 加上那个变量名 后面用不着 但这里不加会报错 就好了
  • 6-JS的Fetch 跨域问题

    跨域访问 只要协议 主机 端口之一不同 就不同源 例如 http localhost 7070 a 和 https localhost 7070 b 就不同源 同源检查是浏览器的行为 而且只针对 fetch xhr 请求 如果是其它客户端