12.跨域问题的解决JSONP

之前了解了跨域,只是有些印象,正好这次前后端分离可以用到,在此详细记录一下。

1.跨域问题:浏览器出于安全考虑,不允许js的ajax跨域请求资源。


跨域的定义:域名端口号不同都是跨域


2.解决跨域问题:本文的解决方案:jsonp



3.jsonp原理:

jsonp即json+padding,动态创建script标签,利用script标签的src属性可以获取任何域下的js脚本,通过这个特性(也可以说是漏洞),服务器端不再返回json格式,而是返回一段调用某个函数的js代码,在src中进行了调用,这样实现了跨域。


4.jsonp解决方案实现

写一个通用的类实现jsonp通用支持,让每一个request的请求都经过该类,若为跨域请求则使用jsonp进行处理,否则就正常处理。该类继承MappingJackson2HttpMessageConverter然后进行扩展。


package com.bdit.common;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonProcessingException;

public class CallbackMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
 // 做jsonp的支持的标识,在请求参数中加该参数
    private String callbackName;

    @Override
    protected void writeInternal(Object object, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
            // 从threadLocal中获取当前的Request对象
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
            String callbackParam = request.getParameter(callbackName);
            System.out.println(callbackParam);
            if(StringUtils.isEmpty(callbackParam)){
                    // 没有找到callback参数,直接返回json数据
                    super.writeInternal(object, outputMessage);
            }else{
                    JsonEncoding encoding = getJsonEncoding(outputMessage.getHeaders().getContentType());
                    try {
                            String result =callbackParam+"("+super.getObjectMapper().writeValueAsString(object)+");";
                            System.out.println(result);
                            IOUtils.write(result, outputMessage.getBody(),encoding.getJavaName());
                    }
                    catch (JsonProcessingException ex) {
                            throw new HttpMessageNotWritableException("Could not write JSON: " + ex.getMessage(), ex);
                    }
            }
            
    }

    public String getCallbackName() {
            return callbackName;
    }

    public void setCallbackName(String callbackName) {
            this.callbackName = callbackName;
    }

}





5.前端调用格式:

前端调用在需要跨域请求的原url上添加?callback=任意函数名,同时需要在ajax的请求中设置数据乐西dataType:"jsonp"。

示例:



关于jsonp优缺点情况这篇文章jsonp的原理,应用场景,优缺点

关于跨域的解决方案请看此篇前后端分离跨域问题解决方案

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值