解决because its MIME type (‘text/plain‘) is not executable, and strict MIME type checking is enabled

1. 问题描述

今天用springboot做了一个接口,返回一个js调用的数据,js使用以下的调用方式:

    $.getScript('http://localhost:8081/a/wx/jssdkInfo?jsonp=setjssdk&link=https%3A%2F%2F3g.xxxx.com%2Fdemo%2F20231127%2Fdemo.html');

或者

    var d=document.createElement('script');
    d.setAttribute('type','text/javascript');
    d.setAttribute('src','http://localhost:8081/a/wx/jssdkInfo?jsonp=setjssdk&link=https%3A%2F%2F3g.xxxx.com%2Fdemo%2F20231127%2Fdemo.html');
    document.getElementsByTagName('head')[0].appendChild(d);

接口方法如下:

    @ResponseBody
    @RequestMapping(value = "/wx/jssdkInfo", method = RequestMethod.GET)
    public String jssdkInfo(HttpServletRequest request, HttpServletResponse response) {
        String callback = ServletUtils.getParameter("jsonp", "callback");
        if (callback == null || callback.equals("")) {
            callback = "callback";
        }
        String signJson = "";
        String jsonpStr = "(function(){ var json=DATA; window['" + callback + "'](json); })();";
        try {
            String link = ServletUtils.getParameter("link", "");
            if (StringUtils.isEmpty(link)) {
                link = request.getHeader("Referer");
            }
            String ticket = extraService.getJsapiTicket(appId, appSecret);
            WeChatSignVo weChatSignVo = extraService.sign(appId, ticket, link);
            signJson = JSONObject.toJSONString(weChatSignVo);
        } catch (Exception e) {
            logger.error("获取jssdkInfo失败", e);
            signJson = "";
        }
        jsonpStr = jsonpStr.replaceAll("DATA", signJson);
        return jsonpStr;
    }

浏览器直接调用接口返回结果如下:

(function(){ var json={"appId":"wx3f30847ss677ca","nonceStr":"3956df8f-dfea-4188-a8c1-eb86e46b5d12","signature":"53779a94c4be877d73ea157cad520f44a3b3119f","timestamp":"1701138083"}; window['setjssdk'](json); })();

但是当我用上面的js调用时,错误出现了:
在这里插入图片描述
没有数据返回,查看详细信息:

在这里插入图片描述

由于我这个功能主要是做微信分享的,所以我在微信开发者工具里面也试一下,结果如下:
在这里插入图片描述

2. 解决思路

2.1 是否是跨域造成的呢?

这里微信的开发者工具给了我误导,让我一直认为是跨域造成的。可是我本身springboot已经解决了跨域问题啊,不论我怎么测试,也没有发现服务存在跨域问题。况且浏览器也没有明确有错误说出现了跨域问题,所以果断放弃了这个方向的探讨;

2.2 X-Content-Type-Options: nosniff 的问题?

既然浏览器给出了这个头,那是不是这个的问题。随着进一步的探讨发现,设置”X-Content-Type-Options: nosniff”响应标头,对 script 和 styleSheet 在执行是通过MIME 类型来过滤掉不安全的文件。
X-Content-Type-Options: nosniff
如果响应中接收到 “nosniff” 指令,则浏览器不会加载“script”文件,除非 MIME 类型匹配以下值之一:

“application/ecmascript”
“application/javascript”
“application/x-javascript”
“text/ecmascript”
“text/javascript”
“text/jscript”
“text/x-javascript”
“text/vbs”
“text/vbscript”

那么显示是我的头信息有问题,并且从浏览器的返回结果看,我这个接口返回的Content-Type是:

Content-Type: text/plain;charset=UTF-8

在这里插入图片描述
那么显然不符合上面的规则。那么问题就定位出来了。

3. 解决问题

修改spirngboot的接口:

    @RequestMapping(value = "/wx/jssdkInfo", method = RequestMethod.GET)
    public void jssdkInfo(HttpServletRequest request, HttpServletResponse response) {
        String callback = ServletUtils.getParameter("jsonp", "callback");
        if (callback == null || callback.equals("")) {
            callback = "callback";
        }
        String signJson = "";
        String jsonpStr = "(function(){ var json=DATA; window['" + callback + "'](json); })();";
        try {
            String link = ServletUtils.getParameter("link", "");
            if (StringUtils.isEmpty(link)) {
                link = request.getHeader("Referer");
            }
            String ticket = extraService.getJsapiTicket(appId, appSecret);
            WeChatSignVo weChatSignVo = extraService.sign(appId, ticket, link);
            signJson = JSONObject.toJSONString(weChatSignVo);
        } catch (Exception e) {
            logger.error("获取jssdkInfo失败", e);
            signJson = "";
        }
        jsonpStr = jsonpStr.replaceAll("DATA", signJson);
        try {
            response.reset();
            response.addHeader("Access-Control-Allow-Origin", "*");
            response.setStatus(200);
            response.setContentType("text/javascript");
            response.setCharacterEncoding("utf-8");
            response.getWriter().print(jsonpStr);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

这里设置了响应头信息:

response.setContentType("text/javascript");

接口返回的数据和之前一样:

(function(){ var json={"appId":"wx3f30847ss677ca","nonceStr":"1f6f164f-b550-4603-98df-23e6d028ba3e","signature":"cfd7998edd0312607b56233c725aef33c1c05f61","timestamp":"1701139151"}; window['setjssdk'](json); })();

页面js调用:
在这里插入图片描述
我们看到有数据了。
头信息:
在这里插入图片描述
返回的Content-type:text/javascript;charset=utf-8

微信开发者工具返回也正常了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值