草庐IT

javascript - 来自 Angular 的 HTTP 请求作为 OPTIONS 而不是 POST 发送

coder 2023-12-31 原文

我正在尝试将一些 HTTP 请求从我的 angular.js 应用程序发送到我的服务器,但我需要解决一些 CORS 错误。

使用以下代码发出 HTTP 请求:

functions.test = function(foo, bar) {
    return $http({
        method: 'POST',
        url: api_endpoint + 'test',
        headers: {
            'foo': 'value',
            'content-type': 'application/json'
        },
        data: {
            bar:'value'
        }
    });
};

第一次尝试以一些 CORS 错误告终。所以我在我的 PHP 脚本中添加了以下几行:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT');
header('Access-Control-Allow-Headers: X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding, X-Auth-Token, content-type');

现在消除了第一个错误。

现在 Chrome 的开发者控制台向我显示以下错误:

angular.js:12011 OPTIONS http://localhost:8000/test (anonymous function)

423ef03a:1 XMLHttpRequest cannot load http://localhost:8000/test. Response for preflight has invalid HTTP status code 400



并且网络请求看起来像我预期的那样(HTTP 状态 400 也是预期的):



我无法想象如何解决这个问题(以及如何理解)为什么请求会在本地主机上发送为 OPTIONS并将远程服务器作为 POST .有没有办法解决这个奇怪的问题?

最佳答案

TL;DR 答案
解释OPTIONS请求被称为 pre-flight request ,它是 Cross-origin resource sharing (CORS) 的一部分.浏览器使用它来检查是否允许来自特定域的请求 如下:

  • 浏览器想要向特定的 URL 发送请求,比如 POST请求 application/json内容类型
  • 首先,它发送飞行前OPTIONS请求相同的 URL
  • 以下内容取决于飞行前请求的响应 HTTP 状态代码:
  • 如果服务器回复一个非 2XX状态响应,浏览器不会发送实际请求(因为他现在知道无论如何都会被拒绝)
  • 如果服务器回复 HTTP 200 OK (或任何其他 2XX )响应,浏览器将发送实际请求 POST在你的情况下


  • 解决方案
    因此,在您的情况下,存在正确的标题,您只需要 确保飞行前请求的响应 HTTP 状态代码为 200 OK或其他一些成功的(2XX) .

    详细说明
    Simple requests
    浏览器 不是 在某些情况下发送飞行前请求,即所谓的简单请求,用于以下情况:
    • One of the allowed methods: - GET - HEAD - POST

  • 除了用户代理自动设置的 headers(例如 Connection、User-Agent 等)之外,唯一允许手动设置的 headers 如下:
  • Accept
  • Accept-Language
  • Content-Language
  • Content-Type (但请注意下面的附加要求)
  • DPR
  • Downlink
  • Save-Data
  • Viewport-Width
  • Width

  • Content-Type header 的唯一允许值是:
  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

  • 没有在任何 XMLHttpRequestUpload 上注册事件监听器请求中使用的对象;这些是使用 XMLHttpRequest.upload 访问的。属性(property)。
  • 没有 ReadableStream请求中使用了对象。

  • 这样的请求是直接发送的,服务器只是成功地处理了请求,或者在它与 CORS 规则不匹配的情况下回复错误。在任何情况下,响应都将包含 CORS header Access-Control-Allow-* .
    Pre-flighted requests
    浏览器 如果实际请求不满足简单请求条件,则发送飞行前请求,最常见的是:
  • 自定义内容类型,如 application/xmlapplication/json等,使用
  • 请求方法不是 GET , HEADPOST
  • POST方法的内容类型不是 application/x-www-form-urlencoded , multipart/form-datatext/plain

  • 您需要 确保对飞行前请求的响应具有以下属性 :
  • 成功的 HTTP 状态码,即 200 OK
  • 标题 Access-Control-Allow-Origin: * (通配符 * 允许来自任何域的请求,当然您可以使用任何特定域来限制访问)

  • 从另一边,服务器可能 拒绝 CORS 请求 只需通过以下属性发送对飞行前请求的响应:
  • 不成功的 HTTP 代码(即 2XX 除外)
  • 成功的 HTTP 代码(例如 200 OK ),但没有任何 CORS header (即 Access-Control-Allow-* )

  • documentation on Mozilla Developer Network或例如 HTML5Rocks' CORS tutorial详情。

    关于javascript - 来自 Angular 的 HTTP 请求作为 OPTIONS 而不是 POST 发送,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40497399/

    有关javascript - 来自 Angular 的 HTTP 请求作为 OPTIONS 而不是 POST 发送的更多相关文章

    1. ruby - RSpec - 使用测试替身作为 block 参数 - 2

      我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

    2. ruby - 如何模拟 Net::HTTP::Post? - 2

      是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

    3. ruby-on-rails - rails : How to make a form post to another controller action - 2

      我知道您通常应该在Rails中使用新建/创建和编辑/更新之间的链接,但我有一个情况需要其他东西。无论如何我可以实现同样的连接吗?我有一个模型表单,我希望它发布数据(类似于新View如何发布到创建操作)。这是我的表格prohibitedthisjobfrombeingsaved: 最佳答案 使用:url选项。=form_for@job,:url=>company_path,:html=>{:method=>:post/:put} 关于ruby-on-rails-rails:Howtomak

    4. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

      在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

    5. ruby - Capistrano 3 在任务中更改 ssh_options - 2

      我尝试使用不同的ssh_options在同一阶段运行capistranov.3任务。我的production.rb说:set:stage,:productionset:user,'deploy'set:ssh_options,{user:'deploy'}通过此配置,capistrano与用户deploy连接,这对于其余的任务是正确的。但是我需要将它连接到服务器中配置良好的an_other_user以完成一项特定任务。然后我的食谱说:...taskswithoriginaluser...task:my_task_with_an_other_userdoset:user,'an_othe

    6. ruby-on-rails - rspec should have_select ('cars' , :options => ['volvo' , 'saab' ] 不工作 - 2

      关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request

    7. ruby - 有人可以帮助解释类创建的 post_initialize 回调吗 (Sandi Metz) - 2

      我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法

    8. jquery - 我的 jquery AJAX POST 请求无需发送 Authenticity Token (Rails) - 2

      rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送

    9. ruby - 字符串文字中的转义状态作为 `String#tr` 的参数 - 2

      对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一

    10. ruby - Net::HTTP 获取源代码和状态 - 2

      我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

    随机推荐