6-JS的Fetch 跨域问题

news2024/12/23 6:48:49

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

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

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

  • 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;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/22356.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

oracle开启归档日志并修改归档日志路径

一、归档日志概念 归档日志&#xff1a;非活动的重做日志&#xff0c;用来保存所有的重做历史记录。 什么时候写归档日志&#xff1a;当数据库处于archivelog模式并重做日志切换的时候&#xff0c;后台进程ARCH会启动将重做日志的内容完整的保存到归档日志中。 日志操作模式…

ZPM介绍(2)

发布您自己的软件 首先&#xff1a;要发布您的软件&#xff0c;您要支持这个”命名规范。其中和zmp最相关的是包名和l类名的设计&#xff0c;你要定义成这样&#xff1a; company.project.subpackage.TheClass.cls 如果您的Package Name定义是&#xff1a; Company.Project, 有…

元数据管理-解决方案调研二:元数据管理解决方案——Saas/内部解决方案(3)

Saas/内部解决方案 2.10、Netflix Metacat Metacat 是一种元数据服务&#xff0c;使数据易于发现、处理和管理。在 Netflix&#xff0c;数据仓库由存储在 Amazon S3&#xff08;通过 Hive&#xff09;、Druid、Elasticsearch、Redshift、Snowflake 和 MySql 中的大量数据集组…

【Linux入门指北】文件服务器

文件服务器 文章目录文件服务器一、FTP Server1.简介2.FTP Server 默认配置3.FTP Clinet4.vsftpd的主动和被动模式二、NFS Server1.简要介绍2.环境配置3.关闭防火墙4.nfs(存储端)5.web1 web2 web3 客户端5.1 安装NFS客户端5.2 开启httpd服务5.3 查看存储端共享5.4 手动挂载5.5 …

电容笔哪个牌子好?2022年电容笔十大品牌排行榜

当电容笔搭配上了ipad&#xff0c;可以大大提升我们的工作效率&#xff0c;不会变得乏味。对于那些对绘画要求很高的人来说&#xff0c;电容笔在绘画中的作用更是不容忽视的。其实我个人对电容笔这块了解还不少的&#xff0c;有着许多平替电容笔都支持在ipad上使用的&#xff0…

社会工程攻击依然是企业面临的最大威胁

企业进入数字化时代&#xff0c;网络攻击行为无处不在&#xff0c;利用社会工程攻击已成黑客的惯用手段。研究表明&#xff0c;91%的网络攻击是通过社会工程手段完成的。 常见的社会工程攻击手段有哪些&#xff1f; 网络钓鱼&#xff1a; 这是经典手段&#xff0c;大多数的钓…

HTML5期末大作业:基于html企业官网项目的设计与实现【艺术官网】

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

Alien Skin Exposure2023调色滤镜插件RAW后期处理软件

Exposure既可以作为ps、lr的插件使用&#xff0c;也可以单独作为一款专业的图像编辑器使用&#xff0c;它可以处理RAW格式的照片&#xff0c;拥有500多种预设滤镜&#xff0c;还有照片管理和添加文字水印等功能。可以说&#xff0c;无论是新手还是设计师和摄影师&#xff0c;都…

【POJ No. 2431】 丛林探险 Expedition

【POJ No. 2431】 丛林探险 Expedition 北大OJ 题目地址 【题意】 一群人开着一辆卡车冒险进入丛林深处&#xff0c;卡车油箱坏了&#xff0c;每走1米就会漏1升油&#xff0c;他们需要到最近的城镇&#xff08;距离不超过106米&#xff09;修理卡车。卡车当前位置和城镇之间有…

怎么将视频转化为gif?

如何将视频转化为gif&#xff1f;gif是一种大家平时常见的动态图片格式&#xff0c;动图是一种非常有意思的图片种类&#xff0c;gif一般都是一些非常有意思的小动图&#xff0c;例如我们在群聊时使用的动态表情包&#xff0c;还有一些球迷朋友喜欢看的足球进球动图等。gif动图…

asp核酸检测预登记系统源码

用asp开发的核酸检测预登记系统上线了&#xff0c;用户填写姓名&#xff0c;手机&#xff0c;身份证号&#xff0c;地址等信息后生成一个加密的二维码&#xff0c;管理员扫码后可以得到真实的二维码文字信息。主要为方便核酸采集统计托底等&#xff0c;也可以用作会议入场信息采…

【NLP】使用 PyTorch 通过 Hugging Face 使用 BERT 和 Transformers 进行情感分析

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

初识Kafka构造组成

在刚学习kafka的时候&#xff0c;有时候会比较纳闷broker是什么&#xff1f;topic又是什么&#xff1f;一台机器上有多少broker&#xff1f;又有多少的topic和partition&#xff1f;由下面这张图来初识我们的kafka&#xff1a; 上图中包含了一个kafka集群的所有组件&#xff1a…

大数据毕业设计题目推荐 毕设选题大全

文章目录0 前言1 如何选题1.1 选题技巧&#xff1a;如何避坑(重中之重)1.2 为什么这么说呢&#xff1f;1.3 难度把控1.4 题目名称1.5 最后2 大数据 - 选题推荐2.1 大数据挖掘类2.2 大数据处理、云计算、区块链 毕设选题2.3 大数据安全类2.4 python大数据 游戏设计、动画设计类2…

LeetCode-808. 分汤【动态规划,概论与统计,记忆化搜索】

LeetCode-808. 分汤【动态规划&#xff0c;概论与统计&#xff0c;记忆化搜索】 题目描述&#xff1a;解题思路一&#xff1a;动态规划&#xff0c;这里将所有的汤除了25&#xff0c;缩小数值。自底向上解题思路二&#xff1a;记忆化搜索&#xff0c;自顶向下搜索&#xff0c;会…

R summarize()分组摘要

summarize()分组摘要分组平均值最大最小值计数 library(nycflights13) library(tidyverse)summarize()可以将数据折叠成一行 如果不与group_by()一起使用&#xff0c;那么summarize()也没什么用 summarize(flights, delay mean(dep_delay, na.rm TRUE))delay12.63907 group…

基于PHP+MySQL仓库管理系统的设计与实现

PHP&#xff1a;MySQL仓库管理系统的设计与实现是一个集合了中小型超市所有特点的一个管理系统, 它使用当下最流行的PHP语言来进行开发,实现了管理员登录,员工登录,超市内物资基本信息管理,进货信息管理,销售信息管理,超市内员工信息管理,查询统计等功能, 通过这些功能可以让超…

Kubernetes云原生实战01 Kubernetes高可用部署架构

大家好&#xff0c;我是飘渺。从今天开始我们将正式开始Kubernetes云原生实战系列&#xff0c;欢迎持续关注。 Kubernets核心组件 Kubernetes中组件众多&#xff0c;要完全介绍清楚估计要写上厚厚一本书&#xff0c;我们实战系列主要记住几个核心组件就行&#xff0c;即两种节…

【LeetCode每日一题:808.分汤~~~边界条件的特判+记忆化搜索】

题目描述 有 A 和 B 两种类型 的汤。一开始每种类型的汤有 n 毫升。有四种分配操作&#xff1a; 提供 100ml 的 汤A 和 0ml 的 汤B 。 提供 75ml 的 汤A 和 25ml 的 汤B 。 提供 50ml 的 汤A 和 50ml 的 汤B 。 提供 25ml 的 汤A 和 75ml 的 汤B 。 当我们把汤分配给某人之后…

vue3项目,vite+vue3+ts+pinia(10)-elementplus布局

项目创建好,接下来引入Container 布局容器, 在src下新建layout文件夹, layoutName.vue <template><el-container><el-aside width"200px">aside</el-aside><el-container><el-header>Header</el-header><el-main>…