【问题标题】:How to post to another domain with ajax如何使用ajax发布到另一个域
【发布时间】:2015-12-02 04:08:12
【问题描述】:

我在一个希望存储一些定制数据的网站(称为 websiteA)上工作。

因此,我们意识到最好的方法是拥有另一个可以处理此问题的网站 (websiteB)。因此,当用户访问 websiteA 时,它会调用 websiteB 并传递一些信息。

我以前使用的代码(我从这篇帖子How to get json from MVC4 C# with no javascript and no Ajax收到的)是

using (var client = new HttpClient())
{
    var responseString = client.GetStringAsync("http://www.example.com/recepticle.aspx?withQueryString=true"); //I don't actually use the responseString 
}

关键是,当我问这个问题时,留下了一条评论(现已删除),说明我应该改用 WebApi。所以我做到了……这就是问题所在。

我创建了 Web Api 2 项目,并使用 Ajax 发布,它可以在我的本地主机上运行。我现在已经部署到我的测试环境并意识到由于跨域来源问题我无法实现我想要的。

进一步阅读表明我不能使用json,但必须使用jsonp 但是jsonp 仅适用于get,而我需要post (How to use type: "POST" in jsonp ajax call )。

我想我可以使用 'get' 并忽略响应,但这感觉就像一个黑客......

很抱歉问了两个问题,但我认为它们非常相关。

问题 1 是:如果 jsonp 需要回调,它实际上是在使用 get 但 get 是从目标机器(websiteB)调用的吗?那么,jsonp 不是从网站 A 发布到网站 B,实际上是否意味着网站 A 将回调传递给网站 B,而网站 B 实际上调用回调(本质上意味着网站 B 正在调用网站 A)?

问题 2(主要问题):如何使用 javascript/ajax/jquery 从网站 A 向网站 B 发布信息。还是我必须在 websiteB 服务器上启用CORS,然后使用 ajax 的 post 和 json?

【问题讨论】:

  • 嗨,我认为这是一个有趣的问题。有问题的框架(MVC-4-C#?)对我来说很模糊,但如果您对通用答案感兴趣,我愿意做一些研究并发布我的发现。
  • 是的,说实话,它是 ASP.NET-MVC 的事实可能无关紧要,因为帖子是在客户端完成的。

标签: asp.net-web-api2


【解决方案1】:

首先,我想介绍这些名称,以使解释不那么混乱。

WebsiteA = App = Web-Client application
WebsiteB = API = Data provider 

问题一:

如果 jsonp 需要回调,它实际上是在使用 get 但 get 是从目标机器(websiteB)调用的吗? 那么,jsonp不是从websiteA发送到websiteB,是不是真的意味着websiteA将回调传递给websiteB,websiteB实际上调用了回调(本质上是websiteB调用websiteA)?

问题一的答案:

API 不会从应用程序调用任何 JavaScript 闭包(回调)。 JSONP 通信技术中的 callback 是客户端上下文中(全局)函数的名称,由 App 本身指定。在从远程服务接收到有效负载后,此回调由 App 调用。根据约定,App 可以指定 padding 函数的名称。这意味着该服务足以让您决定在收到数据后要调用哪个函数。

服务将此函数输出为“纯文本”,因为

App.html

(为简洁起见,语法不正确)

<html>
<head>
<title> Weather App
<script src=weater-station.com/next-week/?callback=parseRemoteWeatherData />
<script>
var app = {
   main: function() { /* init views, etc */ },
   receiveWeatherData: funciton(maybeJson) {
      // validate payload in maybeJson
   }
}

// expose the callback
window.parseRemoteWeatherData = app.receiveWeatherData

对 /next-week/?callback=parseRemoteWeatherData 的 API 响应

HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2.0.61 
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/javascript

parseRemoteWeatherData('any-text, but JSON by convention');

所以简单的解释是:

客户端指定一个函数名,并获取一个以数据为第一个参数调用该函数的脚本。


问题2:

如何使用 javascript/ajax/jquery 将信息从 websiteA 发布到 websiteB。还是我必须在 websiteB 服务器上启用 CORS,然后使用 ajax 的 post 和 json?

回答问题 2

根据CORS(和 HTTP 1.1)规范,您可以向任何服务发出 POST 方法,前提是:

  • Content-Type 标头包含 application/x-www-form-urlencoded、multipart/form-data 或 text/plain 之一。
  • 请求不包含任何自定义标头

如果要发布 Content-Type: application/json,则必须在服务器和客户端上都启用 CORS。服务器必须正确处理OPTION negotiation call(预检请求)并以标头Access-Control-Allow-Origin: * (or the domain name of the client) 进行响应,而客户端必须发送标头Origin: hostname.tld

相关规范

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS https://developer.mozilla.org/en-US/docs/Web/HTTP/Server-Side_Access_Control https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest http://www.w3.org/TR/cors/ https://en.wikipedia.org/wiki/JSONP

【讨论】:

    【解决方案2】:

    Dave Ward 在他的博客上有一篇关于如何做到这一点的完美文章:

    http://encosia.com/using-cors-to-access-asp-net-services-across-domains/

    简而言之,将以下内容放入您的 webconfig。

    <system.webServer>
     <httpProtocol>
      <customHeaders>
       <add name="Access-Control-Allow-Origin" value="*" />
       <add name="Access-Control-Allow-Headers" value="Content-Type" />
      </customHeaders>
     </httpProtocol>
    </system.webServer>
    

    【讨论】:

    • 正确,我建议 Access-Control-Allow-Origin 的值应设置为 WebsiteA(从您发送 AJAX 请求的位置)而不是 *
    • @imVJ 绝对。这是要记住的重要一点。在大多数情况下,* 不应用于生产站点,除非您真的想为所有域启用跨源请求。
    猜你喜欢
    • 2012-07-12
    • 1970-01-01
    • 2018-04-01
    • 2016-06-26
    • 1970-01-01
    • 2012-08-28
    • 2011-01-07
    • 2016-08-03
    • 1970-01-01
    相关资源
    最近更新 更多