【问题标题】:AngularJS: ignoring Content-Type parameterAngularJS:忽略 Content-Type 参数
【发布时间】:2013-02-24 17:16:16
【问题描述】:

我目前正在努力解决 Chrome 开发者工具控制台中出现的错误

GET http://localhost:8080/movie_db/search/movie?movieTitle=Machete 415 (Unsupported Media Type)

当我尝试使用 Angular JS 连接到我的 REST 服务时。由于我在尝试通过 Chrome 中的简单 REST 插件访问 REST 服务之前遇到了这个问题,我认为很可能缺少 Content-Type 标头参数是原因(应该是 Content-Type: 'application/json ')。

Angular JS 网站说,可以将标头参数设置如下:$httpProvider.defaults.headers.get['My-Header']='value'。很遗憾,这没有任何影响,问题仍然存在。

因此,我想知道如何使用发送到我的 REST 服务的 Angular JS 来操作标头参数。

目前,我的代码如下所示:

  function SearchMovieController($scope, $resource) {

  $scope.SearchMovie = $resource('http://localhost\\:8080/movie_db/search/:action',
            {action: 'movie', movieTitle: 'Machete'},
            {get: {method: 'JSONP', headers: [{'Content-Type': 'application/json'}, {'Accept' : 'application/json'}]}});

        $scope.SearchMovie.get()
    }

服务器端如下(我用的是Spring MVC):

控制器:

@Controller
@RequestMapping( "/search/movie" )
public class SearchController { // TODO rename?

private final TheMovieDBService theMovieDBService;

@Autowired
public SearchController( TheMovieDBService theMovieDBService ) {
    this.theMovieDBService = theMovieDBService;
}


@ResponseBody
@RequestMapping( method = RequestMethod.GET, produces = "application/json", consumes = "application/json" )
public Map<String, Object> search( @RequestParam String movieTitle ) {
    Map<String, Object> response = new HashMap<String, Object>();

    try {
        TheMovieDBSearchResult searchResult =  theMovieDBService.searchMovie( movieTitle );
        response.put( "result", searchResult );
        response.put( "success", "true" );
    } catch ( EncoderException e ) {
        response.put( "success", "false" );
    }
    return response;
}
}

web.xml

 <servlet>
    <servlet-name>json</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

    <init-param>
        <param-name>contextClass</param-name>
        <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
    </init-param>

    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>com.u6f6o.apps.movie_db.config.web.ServletConfig</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>json</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

【问题讨论】:

  • 由于您使用的是 JSONP,我认为内容类型无关紧要,除非服务器正在做一些奇怪的事情。 JSONP 向页面添加了&lt;script&gt; 标签,而不是使用 AJAX。
  • 您确定您的 REST 服务设置正确以提供适用于 JSONP 的响应吗?
  • 感谢您的回答@MattB.,我编辑了原始帖子并在服务器端添加了web.xml的控制器代码和内容
  • consumes="application/json" 是问题所在,现在可以了,感谢您指出正确的方向!

标签: javascript rest http-headers angularjs


【解决方案1】:

我最近不得不逐步了解 Angular 的所有 $httpBackend 内容,而 JSONP 使用与其他请求不同的方法来加载数据。

编辑:有问题的代码

因此,如果您指定 jsonp 具有您的方法,它会使用以下方法来加载您的数据。当然,这将完全忽略您自己设置的任何标题。

在 $httpBackend 中:

function jsonpReq(url, done) {
    // we can't use jQuery/jqLite here because jQuery does crazy shit with script elements, e.g.:
    // - fetches local scripts via XHR and evals them
    // - adds and immediately removes script elements from the document
    var script = rawDocument.createElement('script'),
        doneWrapper = function() {
          rawDocument.body.removeChild(script);
          if (done) done();
        };

    script.type = 'text/javascript';
    script.src = url;

    if (msie) {
      script.onreadystatechange = function() {
        if (/loaded|complete/.test(script.readyState)) doneWrapper();
      };
    } else {
      script.onload = script.onerror = doneWrapper;
    }

    rawDocument.body.appendChild(script);
  }

【讨论】:

  • 谢谢,所以使用jsonp时没有办法指定header参数?
  • 对于 JSONP,您只能在服务器端设置 headers。客户端将始终假定&lt;script&gt; 标记的src 指向text/javascript 类型的文件(除非您设置不同的type 属性,这仅在您使用VBScript 或其他东西时才相关)。请记住,它就像任何其他 &lt;script&gt; 标记一样,只是它是在初始页面加载之后加载的。
猜你喜欢
  • 2020-10-27
  • 1970-01-01
  • 2020-07-03
  • 2013-03-21
  • 2014-11-17
  • 2015-07-08
  • 2014-03-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多