简体   繁体   中英

Content Type Not being set on JSONP Request From Two Different Ports

This situation is killing me. A JSONP Jquery Ajax request from http://example.com:80 to http://example1.com:8080 never sets the Content Type and Spring MVC complains on the server when trying to serialize my javabean in the controller parameter. If I test the JSONP request on either website calling the same domain, it sets the content type. Is this a port issue? I am testing a Wordpress site to Spring MVC API on my local.

handlerMapperInvoker.java - This is where the error occurs in the Spring Framework

MediaType contentType = inputMessage.getHeaders().getContentType();
        if (contentType == null) {
            StringBuilder builder = new StringBuilder(ClassUtils.getShortName(methodParam.getParameterType()));
            String paramName = methodParam.getParameterName();
            if (paramName != null) {
                builder.append(' ');
                builder.append(paramName);
            }
            throw new HttpMediaTypeNotSupportedException(
                    "Cannot extract parameter (" + builder.toString() + "): no Content-Type found");
    }

apicontroller.java - API Side

@RequestMapping(value="/badge/get")
public @ResponseBody IHttpResponse getBadge(@RequestBody GetBadgeRequest request) {

    apiService.getBadge(request);

    return request.getResponse();
}

api.js - Wordpress

getBadge : function(id) {

        var model = 
        {
            id : id
        };

        this.call({ url: 'badge/get.json', type: 'GET', data: model, callback: function(data)
        {
            alert(data);
        }});
    },

call : function(options) {

        var def = {
            url : '',
            type : "POST",
            dataType : 'jsonp',
            data : undefined,
            contentType : "application/json",
            callback : function() {},
            errorCallback : function() {}
        };

        $.extend(def, options);

        var sessionToken = api.getSession();

        if(sessionToken && sessionToken != "undefined") {
            if(!def.data) {
                def.data = {};
            }

            def.data.sessionToken = sessionToken;
        }

        var url = config.baseUrl + def.url;

        // Abort Request If Another One Is Made
        if (config.request != null)
            config.request.abort();

        if (def.showLoader) {
            application.loader(true);
        }

        config.request = $
                .ajax({
                    url : url,
                    type : def.type,
                    data : { request: $.toJSON(def.data) },
                    dataType : def.dataType,
                    contentType : def.contentType,
                    success : function(data) {
                        if (def.showLoader) {

JSONP requests outside the current domain are always made as script requests to get around the same origin policy. The parameters will be encoded into the url (ie, no POST, only a GET for a script). Since there's no way to specify a content type on a script request, it doesn't appear. When done locally, it keeps the content type since it's actually making a real AJAX request.

Essentially what an AJAX request for JSONP to a different domain translates to is:

<script type="text/javascript" src="http://example1.com:8080/badge/get.json?request=...&callback=somefunction">
</script>

And it expects to receive in return a script like:

somefunction( { ... your json here ... } );

Note when using jQuery somefunction is actually an automatically generated name.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM