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

文章目录

  • 核心原理
  • 代码
    • 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>

服务端目录结构

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Jenkins+Docker+Docker-Compose自动部署,SpringCloud架构公共包一个任务配置

前言 Jenkins和docker的安装&#xff0c;随便百度吧&#xff0c;实际场景中我们很多微服务的架构&#xff0c;都是有公共包&#xff0c;肯定是希望一个任务能够把公共包的配置加进去&#xff0c;一并构建&#xff0c;ok&#xff0c;直接上干货。 Jenkins 全局环境安装 pwd e…

使用SpringBoot+SpringMVC+Mybatis+Redis实现个人博客管理平台

文章目录 前言1. 项目概述2. 项目需求2.1功能需求2.2 其他需求2.3 系统功能模块图 3. 开发环境4. 项目结构5. 部分功能介绍5.1 数据库密码密文存储5.2 统一数据格式返回5.3 登录拦截器 6. 项目展示 前言 在几个月前实现了一个servlet版本的博客系统&#xff0c;本项目则是在原…

左神算法之中级提升班(8)

目录 【案例1】 【题目描述】 【思路解析】 【代码实现】 【案例2】 【题目描述】 【思路解析】 【代码实现】 【案例3】 【题目描述】 【思路解析】 【案例4】 【题目描述】 【思路解析】 【代码实现】 【案例5】 【题目描述】 【子序列概念】 【思路解析1 经典…

【C++】STL中list的模拟实现(增删查改,迭代器封装,运算符重载)

文章目录 前言大体框架&#xff1a; 一、节点的封装&#xff08;list_node&#xff09;二、迭代器的封装(_list_iterator)1.类模板的定义&#xff1a;2.构造函数3.前置&#xff0c;后置4.前置--&#xff0c;后置--5.解引用(operator*())6. ->重载&#xff08;operator- >…

关于提示词 Prompt

Prompt原则 原则1 提供清晰明确的指示 注意在提示词中添加正确的分割符号 prompt """ 请给出下面文本的摘要&#xff1a; <你的文本> """可以指定输出格式&#xff0c;如&#xff1a;Json、HTML提示词中可以提供少量实例&#xff0c;…

Android 面试题 ANR 五

&#x1f525; 什么是 ANR &#x1f525; ANR(Application Not Responding )应用无响应的简称&#xff0c;是为了在 APP卡死时&#xff0c;用户 可以强制退出APP的选择&#xff0c;从而避免卡机无响应问题&#xff0c;这是Android系统的一种自我保护机制。 在Android中&#xf…

【无标题】使用Debate Dynamics在知识图谱上进行推理(2020)7.31

使用Debate Dynamics在知识图谱上进行推理 摘要介绍背景与相关工作我们的方法 摘要 我们提出了一种新的基于 Debate Dynamics 的知识图谱自动推理方法。 其主要思想是将三重分类任务定义为两个强化学习主体之间的辩论游戏&#xff0c;这两个主体提取论点&#xff08;知识图中…

fixed-视频倍速

首先fn12打开开发者模式 然后进入console控制台 document.getElementsByTagName(“video”)[0].playbackRate 3 数字3 就是多少倍速 可以替换想要的倍速 直接快进到 最后 let video document.getElementsByTagName(‘video’) for (let i0; i<video.length; i) { video[…

音频编辑必备技能:怎么将音频转换mp3

丽萨&#xff1a;嘿&#xff0c;听说你最近在研究音频格式转换的方法&#xff0c;有眉目了吗&#xff1f; 凯瑞&#xff1a;没错&#xff0c;我下载了很多高清音乐&#xff0c;发现有些格式的音频文件在我的播放器上打不开&#xff0c;所以想一个转换工具。但是网上软件太多&a…

树莓派通过天线+gps获取经纬度并调用高德地图api在地图上标点

完整项目为《基于机器视觉的行人和路面缺陷检测及其边缘设备部署》 完整功能视频演示地址&#xff1a;本科最后的课设&#xff1a;“车载系统的辅助系统——基于机器视觉的行人和路面缺陷检测”完结撒花*罒▽罒*_哔哩哔哩_bilibili 该博客介绍的功能为&#xff1a; 1&#xff1…

学会这13个问题,轻松拿捏Java容器面试

java 容器都有哪些&#xff1f; 常用容器的图录&#xff1a; Collection 和 Collections 有什么区别&#xff1f; java.util.Collection 是一个集合接口&#xff08;集合类的一个顶级接口&#xff09;。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java …

【SpringBoot】| SpringBoot 和 web组件

目录 一&#xff1a;SpringBoot 和 web组件 1. SpringBoot中使用拦截器&#xff08;重点&#xff09; 2. SpringBoot中使用Servlet 3. SpringBoot中使用过滤器&#xff08;重点&#xff09; 4. 字符集过滤器的应用 一&#xff1a;SpringBoot 和 web组件 1. SpringBoot中使…

基于双层优化的微电网系统规划设计方法(Matlab代码实现)

目录 &#x1f4a5;1 概述 1.1 微电网系统结构 1.2 微电网系统双层规划设计结构 1.3 双层优化模型 1.4 上层容量优化模型 1.5 下层调度优化模型 &#x1f4da;2 运行结果 &#x1f389;3 文献来源 &#x1f308;4 Matlab代码、数据、文章讲解 &#x1f4a5;1 概述 文献来源&…

MySQL:MHA高可用集群部署及故障切换

目录 一、MHA概述 1、什么是MHA 2、MHA 的组成 3、MHA 的特点 4、MHA的工作原理 二、搭建MHA环境 主 从 manager 一、MHA概述 1、什么是MHA MHA&#xff08;MasterHigh Availability&#xff09;是一套优秀的MySQL高可用环境下故障切换和主从复制的软件。 MHA 的出现…

消息中间件ActiveMQ介绍

一、消息中间件的介绍 介绍 ​ 消息队列 是指利用 高效可靠 的 消息传递机制 进行与平台无关的 数据交流&#xff0c;并基于 数据通信 来进行分布式系统的集成。 特点(作用) 应用解耦 异步通信 流量削峰 (海量)日志处理 消息通讯 …... 应用场景 根据消息队列的特点&a…

Android adb shell 查看App内存(java堆内存/vss虚拟内存/详细的内存状况/内存快照hprof)和系统可用内存

1.adb shell 获取app 进程的pid adb shell "ps|grep com.xxx包名"根据某个渠道包&#xff0c;去查询对应的pid&#xff0c;如下所示&#xff1a; 2.通过adb shell 查看设备的java dalvik 堆内存的最大值 执行命令行&#xff1a; adb shell getprop dalvik.vm.h…

【RabbitMQ】之消息的可靠性方案

目录 一、数据丢失场景二、数据可靠性方案 1、生产者丢失消息解决方案2、MQ 队列丢失消息解决方案3、消费者丢失消息解决方案 一、数据丢失场景 MQ 消息数据完整的链路为&#xff1a;从 Producer 发送消息到 RabbitMQ 服务器中&#xff0c;再由 Broker 服务的 Exchange 根据…

微服务项目,maven无法加载其他服务依赖

微服务项目&#xff0c;导入了工具类工程&#xff0c;但是一直报错&#xff0c;没有该类&#xff0c; 检查maven 这里的Maven的版本与idea版本不匹配可能是导致依赖加载失败的最重要原因 检查maven配置&#xff0c;我这是原来的maven&#xff0c;home 修改之后,就不报错了

python文件处理方式

python文件处理方式 file open(D:\pythonText.txt, r, encodingUTF-8) print(file) # <_io.TextIOWrapper nameD:\\pythonText.txt moder encodingUTF-8> print(type(file)) # <class _io.TextIOWrapper>读取文件 file open(D:\pythonText.txt, r, encodingU…

C#文件操作从入门到精通(2)——查看某个dll中有哪些函数

kernel32.dll中含有ini文件操作使用的函数,我们可以通过VisualStudio自带的dumpbin.exe查看dll所包含的函数,操作步骤如下: 1、找到dumpbin.exe所在的文件夹 我的电脑中安装了VisualStudio2019社区版以及VisualStudio2017Professional,但是我发现VisualStudio2019社区版中…