AJAX解决跨域(包括json)

1 分析AJAX的contentType

ajaxcontentType指的是传递data到后端所使用内容格式,我们这里主要说两种

xwwwformurlencoded

这是ajax默认数据传输格式,是在请求体当中通过键值对的格式进行传输的,如下

name=1&age=12

这种方法一个缺憾,就是当传复杂嵌套数据对象的时候,无法正确解析比如

data:{
    name:"zong",
    age:"12",
    teacher: {
        name :"wang",
        age:"25"
    }
}

代码使用如下

  $.ajax({
            url:"http://localhost:8081/blog/t",
            type:"post",
            data:  {
                "tagId":"1",
                "tagName":"2",
                "total":"1",
            ),
            success:function(obj){
                alert(123)
            },
        })

后端接收

    @RequestMapping("/test")
    public Map<String,Object> test(BlogTag blogTag){
        Map<String,Object> datas = new HashMap<>();
        System.out.println(blogTag);
        return datas;
    }

json

这是一种流行的数据传输格式,通过json字符串的格式传输数据支持嵌套

代码使用如下

$.ajax({
            url:"http://localhost:8081/blog/t",
            type:"post",
            data:  JSON.stringify({
                "tagId":"1",
                "tagName":"2",
                "total":"1",
            }), // 序列化json字符串
            contentType: "application/json", //指定请求
            dataType:'json',
            success:function(obj){
                alert(123)
            },
        })

后端接收

    @RequestMapping("/test")  // 如果设置为ResponseBody就对前端contentType有要求,会自动序列化
    public Map<String,Object> test(@RequestBody  BlogTag blogTag){
        Map<String,Object> datas = new HashMap<>();
        System.out.println(blogTag );
        return datas;
    }

2 跨域问题出现

在这里插入图片描述

CORS,跨域问题

我们着重看后面的内容需要打开服务器客户端的Access-Control-Allow-Origin

我们编写一个过滤器

package com.zong.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebFilter(urlPatterns = "/*", filterName = "CORSFilter")
public class CORSFilter implements Filter {
    /**
     * 此过滤器只是处理跨域问题
     * @param servletRequest
     * @param servletResponse
     * @param chain
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
        String origin = req.getHeader("Origin");
        if(origin == null) {
            origin = req.getHeader("Referer");
        }

        resp.setHeader("Access-Control-Allow-Origin", origin); // 解决跨域核心代码,放行的客户端
       
//        resp.setHeader("Access-Control-Allow-Credentials", "true");
        //true代表允许携带cookie,这行代码需要前端传输的时候添加请求头withCredentials = true 两个设置true 才起效
        
        chain.doFilter(servletRequest,servletResponse);
    }
}


这样,x-wwwform-unlencoded可以正常通信,但是json格式的数据还是报跨域问题

为什么

我们先了解一下两种格式在传输时的不同

预检 (preflight request

contentType为json的时候,ajax会先发送一个preflight request 到后端,如图

在这里插入图片描述

这个预检,会对要传输数据的一些信息放入请求

在这里插入图片描述

服务端需要对这些请求头,做出响应,如果不响应就会出现如图这种跨域问题
在这里插入图片描述

注意这个in preflight response

解决问题

现在我们出现一个问题就解决一个问题呗,需要响应头,我们就给他响应
在这里插入图片描述
上图转载自:Access-Control-Allow-Headers是什么?有什么作用?

package com.zong.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebFilter(urlPatterns = "/*", filterName = "CORSFilter")
public class CORSFilter implements Filter {
    /**
     * 此过滤器只是处理跨域问题
     * @param servletRequest
     * @param servletResponse
     * @param chain
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
        String origin = req.getHeader("Origin");
        if(origin == null) {
            origin = req.getHeader("Referer");
        }
        resp.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
        resp.setHeader("Access-Control-Allow-Headers", "Content-Type,XFILENAME,XFILECATEGORY,XFILESIZE,x-requested-with,Authorization"); // 设置Content-Type,如上面说的那三种由于不需要预检,所以这里的Content-Type指的是json
        resp.setHeader("Access-Control-Allow-Origin", origin);//这里不能写*,*代表接受所有域名访问,如写*则下面一行代码无效。谨记
        resp.setHeader("Access-Control-Allow-Credentials", "true");//true代表允许携带cookie
        chain.doFilter(servletRequest,servletResponse);
    }
}

如此问题全部解决

原文地址:https://blog.csdn.net/weixin_47554687/article/details/127800976

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_15575.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注