【问题标题】:jQuery sends OPTIONS instead of POST request to REST on localhostjQuery 向本地主机上的 REST 发送 OPTIONS 而不是 POST 请求
【发布时间】:2014-04-10 19:21:16
【问题描述】:

我正在尝试通过 POST 向我的 REST 资源 (Java) 发送表单,但我无法这样做,因为我的请求是作为 OPTIONS 发送的。我知道 REST 资源很好,因为在我使用 Poster Firefox 进行测试时它可以完美运行。

jQuery/Ajax 调用

function loadTwitter(){
            arrayTweets = new Array();
            var urlTwitter = "http://localhost:8081/streamingvideoservice/services/twitter/retrieveTweets";
            $.ajax({
                    type: "POST",
                    url: urlTwitter,
                    contentType: "application/x-www-form-urlencoded",
                    //accept: "application/json",
                    data: $("form#mapForm").serialize(),
                    dataType: "json",
                    async: false,
                    success: function (resp, status, xhr) {
                       $("#message").html("STATUS: " + xhr.status + " " + xhr.statusText + "\n" + resp);
                       $("#message").hide();
                       $.each(resp, function() {
                            $.each(this, function(i, item) {
                                arrayTweets.push(item);
                            });

                        });

                        displayTweets();
                    },
                    error: function(resp, status, xhr){
                        $("#message").html("ERROR: " + xhr.status + " " + xhr.statusText + "\n" + resp.e);
                        $("#message").show();
                    }
                });
        }

REST 资源

    @POST
    @Path("/retrieveTweets")
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    @Produces("application/json")
    public List<Tweet> retrieve(@FormParam("lat") Double Latitude, @FormParam("lon") Double Longitude, @FormParam("rad") Integer Radius, @FormParam("from") String From, @FormParam("to") String To) {

        ArrayList<Tweet> lTweets = new ArrayList<Tweet>();
        boolean status = false;

        Twitter twitter = new TwitterFactory().getInstance();

        AccessToken accessToken = new AccessToken(TwitterInterface.ACCESS_TOKEN, TwitterInterface.ACCESS_TOKEN_SECRET);
        twitter.setOAuthConsumer(TwitterInterface.CONSUMER_KEY, TwitterInterface.CONSUMER_SECRET);
        twitter.setOAuthAccessToken(accessToken);

        try {
            Query query = new Query("");
            GeoLocation geo =  new GeoLocation(Latitude, Longitude);
            query.setGeoCode(geo, Radius, Query.KILOMETERS);
            query.setCount(100);
            query.setSince(From);
            query.setUntil(To);
            QueryResult result;
            result = twitter.search(query);
            List<Status> tweets = result.getTweets();
            for (Status tweet : tweets) {
                System.out.println("@" + tweet.getUser().getScreenName() + " - " + tweet.getText() + " - " + tweet.getCreatedAt());
                Tweet t = new Tweet();
                t.setUser(tweet.getUser().getScreenName());
                t.setText(tweet.getText());
                lTweets.add(t);
            }
        }
        catch (TwitterException te) {
            te.printStackTrace();
            System.out.println("Failed to search tweets: " + te.getMessage());
            System.exit(-1);
        }

        return lTweets;

    }

我正在使用 jQuery 1.9.1 并将资源托管在 Tomcat 6 上。

感谢任何帮助。

提前致谢。

【问题讨论】:

  • 你在做一些CORS(跨域资源共享)请求吗?
  • 它都在同一台机器上......所以它是一个本地主机调用(正如你在我的 ajax 调用中看到的那样)。是这个意思吗?
  • @Maged 主机(本地主机)不是决定它是否是跨域的。 端口也很重要。您当前的网络应用程序是否也在端口 8081 上运行?
  • 正确的 8081。为了给你一个更好的图片,它是一个简单的 HTML 页面,调用在 tomcat 上运行的资源。

标签: javascript jquery ajax rest post


【解决方案1】:

您似乎正在发出跨源 Ajax 请求。这就要求服务端提供一个Access-Control-Allow-Origin标头来授予承载该JS页面的站点读取数据的权限。

关于请求的某些内容(可能是 jQuery 添加到 Ajax 请求的 X-Requested-With 标头)正在触发 preflight request,它使用 OPTIONS 请求在发出主请求之前向服务器请求许可。

您需要根据 CORS 规范(上面链接)配置服务器以提供带有合适访问控制标头的 OPTIONS 响应。

【讨论】:

  • 感谢您的回答,我阅读了您发送给我的链接,但是如何让我的资源提供“访问控制允许来源”是 Java 部分,还是服务器上的东西? (正如我提到的,我正在我的机器上运行整个东西;HTML 页面调用资源运行 tomcat。
  • .htaccess 文件可以做到。
  • 对不起,我在这里感到困惑。我必须在我的应用程序服务器或 Web 应用程序上创建此文件吗?里面必须有什么样的命令?
  • @Maged — 您发出请求的服务器(即http://localhost:8081)必须能够响应 OPTIONS 请求和将在 OPTIONS 请求中发送的 POST 请求良好的反应。您应该响应的标题的细节在我在答案中链接到的规范中。有关其他文档,请参阅 developer.mozilla.org/en/docs/HTTP/Access_control_CORS
  • 出于某种原因,我读到“Apache Tomcat”,也许他只是在使用 Tomcat?
【解决方案2】:

改为使用GET 解决它并在 URI 中传递参数。

【讨论】:

    猜你喜欢
    • 2014-04-16
    • 1970-01-01
    • 1970-01-01
    • 2018-12-04
    • 2012-02-20
    • 1970-01-01
    • 2017-03-22
    • 2021-07-01
    相关资源
    最近更新 更多