jsonp 实现跨域 同时也是一个 webflux 的demo 示例

news2024/9/28 23:37:37

文章目录

  • 核心原理
  • 代码
    • html
    • 服务端 (java 为例子)
    • 服务端目录结构


核心原理

  • 前端: 使用js 创建 script 标签,将请求地址,放到其src 中,并将 script 标签追加到文档流;
  • 后端:根据约定好的 callback 字段,将 callback中的函数名 拼接成函数调用返回,类似callback_fun('+ data +');
  • 前端认为返回的是js 会立即执行 callback_fun 函数,而此函数参数为数据,函数本身可以完成数据解析和展示的功能;

代码

html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>jsonp 实现跨域</title>
</head>
<style>
      body {
        margin: 0;
        padding: 0;
      }
      #wrapper {
        text-align: center;
        padding-top: 100px;
      }
      #searchBar {
        display: inline-block;
      }
      #input {
        width: 300px;
        height: 20px;
        padding: 9px 7px;
        border: 1px solid #b8b8b8;
        border-right: 1px solid #38f;
        outline: none;
        vertical-align: top;
      }
      #btn {
        border: 1px solid #38f;
        margin-left: -5px;
        display: inline-block;
        vertical-align: top;
      }
      #btn input {
        width: 102px;
        height: 38px;
        border: none;
        background: gray;
        cursor: pointer;
        font-size: 14px;
        color: #fff;
      }
      #btn input:hover {
        background-color: #317ef3;
        border-color: #317ef3;
      }
      #title {
        font-size: 12px;
      }
      ul {
        list-style: none;
      }
      li {
        padding: 10px 0;
      }
    </style>
<body>
	<div id="wrapper">
		<div id="searchBar">
			<input type="text" maxlength="50" id="input">
			<span id="btn">
			  <input type="button" value="jsonp_call" onclick="custom()">
			</span>
		</div>
		<p id="title">接口返回数据:</p>
	 </div>
</body>
	<script>
        
		function custom() {
			var input = document.getElementById('input');
			var inputVal = input.value;
			var url = "http://127.0.0.1:8080/api/jsonp_call?code=utf-8&query="+inputVal+"&callback=commonParse";
			var script = document.createElement('script');
			script.setAttribute('src', url);
			document.getElementsByTagName('head')[0].appendChild(script);
		}

	  
	  function showData(ui_element) {
		var wrapper = document.getElementById('wrapper');
		wrapper.appendChild(ui_element);
	  }
	  
	  var commonParse = function (data) {
		pTag = document.createElement('p');
		pTag.innerHTML = JSON.stringify(data);
		showData(pTag);
	  }
		var input = document.getElementById('input');
		input.addEventListener('keydown', function(e) {
			if (e.key === 'Enter') {
				custom();
			}
		})
	  
	</script>
</html>

服务端 (java 为例子)

  • controller:
package com.qww.reactivedemo.controller;

import com.alibaba.fastjson2.JSON;
import com.qww.reactivedemo.dao.MySQLDao;
import com.qww.reactivedemo.pojo.User;
import org.springframework.http.MediaType;
import org.springframework.util.StopWatch;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api")
public class CommonController {

    @Resource
    MySQLDao mySQLDao;

    @RequestMapping(value = "/jsonp_call", produces = MediaType.APPLICATION_JSON_VALUE + ";charset=utf-8")
    public String jsonp(String code, String callback, @RequestParam Map<String,Object> body){
        Map<String,Object> result = new HashMap<>();
        result.put("code", code);
        result.put("callback", callback);
        result.put("body", body);
        return callback + "("+ JSON.toJSONString(result) + ")";
    }
	 
	@GetMapping("/find_all")
    public Flux<User> index(){
        StopWatch find_all = new StopWatch("find_all");
        find_all.start();
        Flux<User> all = mySQLDao.findAll();
        find_all.stop();
        System.out.println(find_all.prettyPrint());
        return all;
    }
}

  • dao:
package com.qww.reactivedemo.dao;

import com.qww.reactivedemo.pojo.User;
import org.reactivestreams.Publisher;
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@Repository
public interface MySQLDao  extends ReactiveCrudRepository<User,Integer>{}

  • pojo
package com.qww.reactivedemo.pojo;

public class User {
    private Integer uid;
    private String uname;
    private String pwd;

    public Integer getUid() {
        return uid;
    }

    public void setUid(Integer uid) {
        this.uid = uid;
    }

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
}

  • mainApp:
package com.qww.reactivedemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ReactiveDemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(ReactiveDemoApplication.class, args);
	}

}

  • pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<!--<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.7.10</version>
		<relativePath/> &lt;!&ndash; lookup parent from repository &ndash;&gt;
	</parent>-->

	<groupId>com.qww</groupId>
	<artifactId>reactive-demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>reactive-demo</name>
	<description>reactive Demo project for Spring Boot</description>
	<properties>
		<java.version>1.8</java.version>
		<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
	</properties>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-dependencies</artifactId>
				<version>${spring-boot.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-r2dbc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-webflux</artifactId>
		</dependency>
		<!--<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>2.3.0</version>
		</dependency>-->

		<dependency>
			<groupId>dev.miku</groupId>
			<artifactId>r2dbc-mysql</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>2.0.36</version>
		</dependency>


		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>8</source>
					<target>8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>

</project>

服务端目录结构

在这里插入图片描述

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

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

相关文章

Latex好看的引用(文献,url, 文内引用)

强迫症实锤了&#xff0c;完全符合本人审美&#xff01;&#xff01;&#xff01; \usepackage{hyperref} \hypersetup{ hidelinks, colorlinkstrue, linkcolorIndigo, urlcolorDeepSkyBlue4, citecolorIndigo }基本还原了 哼&#xff0c;欺负老子色彩妹那么敏感是吧&…

WIZnet W51000S-EVB-PICO 入门教程(一)

概述 W5100S-EVB-Pico是基于树莓派RP2040和全硬件TCP/IP协议栈控制器W5100S的微控制器开发板-基本上与树莓派Pico板相同&#xff0c;但通过W5100S芯片增加了以太网功能。 W5100S-EVB-Pico特点 RP2040规格参数 双核Arm Cortex-M0 133MHz264KB 高速SRAM和2MB板载内存通过…

Docker复杂命令便捷操作

启动所有状态为Created的容器 要启动所有状态为"created"的Docker容器&#xff0c;可以使用以下命令&#xff1a; docker container start $(docker container ls -aq --filter "statuscreated")上述命令执行了以下步骤&#xff1a; docker container l…

【Linux】-进程概念及初始fork

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树&#x1f388; &#x1f389;作者宣言&#xff1a;认真写好每一篇博客&#x1f4a4; &#x1f38a;作者gitee:gitee✨ &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 动态规划算法&#x1f384; 如 果 你 …

C++ 拷贝构造函数

拷贝构造函数是一种特殊的构造函数&#xff0c;具有一般构造函数的所有特性&#xff0c;其形参是本类的对象的引用。其作用是使用一个已经存在的对象&#xff08;由拷贝构造函数的参数指定&#xff09;&#xff0c;去初始化同类的一个新对象。 如果程序员没有定义类的拷贝构造函…

自动驾驶感知系统--惯性导航定位系统

惯性导航定位 惯性是所有质量体本身的基本属性&#xff0c;所以建立在牛顿定律基础上的惯性导航系统&#xff08;Inertial Navigation System,INS&#xff09;(简称惯导系统)不与外界发生任何光电联系&#xff0c;仅靠系统本身就能对车辆进行连续的三维定位和三维定向。卫星导…

Ubuntu-文件和目录相关命令一

&#x1f52e;linux的文件系统结构 ⛳目录结构及目录路径 &#x1f9e9;文件系统层次结构标准FHS Filesystem Hierarchy Standard(文件系统层次结构标准&#xff09; Linux是开源的软件&#xff0c;各Linux发行机构都可以按照自己的需求对文件系统进行裁剪&#xff0c;所以众多…

MyBatisPlus从入门到精通-3

紧接着上一篇的查询 接下来的重点介绍增删改操作了 Insert id&#xff08;主键&#xff09;生成策略 前面的案列中我们没有指定id字段 但是它是生成了一个很长的id&#xff0c;并不是我们数据表定义自增 这是Mp内部算法出来的一个值 其实根据不同应用场景&#xff0c;应该使…

抖音SEO源代码的部署与搭建技巧详解

抖音SEO源代码的部署与搭建是一项重要的技术&#xff0c;促进了抖音的发展。在此&#xff0c;我将为大家详细介绍抖音SEO源代码的部署与搭建技巧。 首先&#xff0c;我们需要了解抖音SEO源代码的含义。SEO源代码是搜索引擎优化的核心&#xff0c;它是用于帮助搜索引擎更好地理解…

PHP使用Redis实战实录3:数据类型比较、大小限制和性能扩展

PHP使用Redis实战实录系列 PHP使用Redis实战实录1&#xff1a;宝塔环境搭建、6379端口配置、Redis服务启动失败解决方案PHP使用Redis实战实录2&#xff1a;Redis扩展方法和PHP连接Redis的多种方案PHP使用Redis实战实录3&#xff1a;数据类型比较、大小限制和性能扩展 数据类型…

pytorch的发展历史,与其他框架的联系

我一直是这样以为的&#xff1a;pytorch的底层实现是c(这一点没有问题&#xff0c;见下边的pytorch结构图),然后这个部分顺理成章的被命名为torch,并提供c接口,我们在python中常用的是带有python接口的&#xff0c;所以被称为pytorch。昨天无意中看到Torch是由lua语言写的&…

docker 部署 mysql8.0 无法访问

文章目录 &#x1f5fd;先来说我的是什么情况&#x1fa81;问题描述&#x1fa81;解决方法&#xff1a;✔️1 重启iptables✔️2 重启docker &#x1fa81;其他有可能连不上的原因✔️1 客户端不支持caching_sha2_password的加密方式✔️2 my.conf 配置只有本机可以访问 &#…

用JavaScript和HTML实现一个精美的计算器

文章目录 一、前言二、技术栈三、功能实现3.1 引入样式3.2 编写显示页面3.2 美化计算器页面3.3 实现计算器逻辑 四、总结 一、前言 计算器是我们日常生活中经常使用的工具之一&#xff0c;可以帮助我们进行简单的数学运算。在本博文中&#xff0c;我将使用JavaScript编写一个漂…

【我们一起60天准备考研算法面试(大全)-第二十八天 28/60】【枚举】

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&#xff09;   文章字体风格&#xff1a; 红色文字表示&#…

VBA技术资料MF35:VBA_在Excel中过滤数据

【分享成果&#xff0c;随喜正能量】好马好在腿&#xff0c;好人好在嘴。不会烧香得罪神&#xff0c;不会讲话得罪人。慢慢的你就会发现&#xff0c;一颗好心&#xff0c;永远比不上一张好嘴。。 我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#…

Android实例——自定义控件

自定义View 对现有控件进行扩展 案例一&#xff1a;添加背景 如下继承TextView public class MyTextView extends androidx.appcompat.widget.AppCompatTextView {private Paint mPaint1;private Paint mPaint2;public MyTextView(Context context) {this(context, null);}…

wireshark抓包新手使用教程(超详细)

一、简介 Wireshark是一款非常流行的网络封包分析软件&#xff0c;可以截取各种网络数据包&#xff0c;并显示数据包详细信息。 为了安全考虑&#xff0c;wireshark只能查看封包&#xff0c;而不能修改封包的内容&#xff0c;或者发送封包。 wireshark能获取HTTP&#xff0c;也…

day47-Testimonial Box Switcher(推荐箱切换器-动态进度条自动更新卡片信息)

50 天学习 50 个项目 - HTMLCSS and JavaScript day47-Testimonial Box Switcher&#xff08;推荐箱切换器-动态进度条自动更新卡片信息&#xff09; 效果 index.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"…

Docker续集+Docker Compose

目录 Containerd与docker的关系 runCrunC与Containerd的关联 OCI协议Dockerfile多阶段构建&#xff08;解决&#xff1a;如何让一个镜像变得更小 &#xff09;多阶段构建Images瘦身实践.dockerignore Docker Compose快速开始Quick StartCompose 命令常用命令命令说明 Compose 模…

11. Mybatis 的增删查改【万字详解】

目录 1. 数据的查找 select 1.1 查询所有数据 1.2 通过 id 进行查找 2. 插入数据 insert 3. 修改数据 update 4. 删除数据 delete 5. $ 和 # 的区别 5.1 SQL 注入 用户登录 6. Spring Boot 打印 SQL 日志 7. order by 排序 8. like 查询 9. 通过页面返回数据 10. …