如何使用ajax发布到另一个域

时间:2015-09-06 14:15:35

标签: asp.net-web-api2

我在一个想要存储一些定制数据的网站(名为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需要postHow to use type: "POST" in jsonp ajax call)。

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

很抱歉提出2个问题,但我认为它们非常相关。

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

问题2 (主要问题):如何使用javascript / ajax / jquery 从websiteA发布信息到websiteB。或者我是否必须在websiteB服务器上启用CORS然后使用ajax的帖子和json?

2 个答案:

答案 0 :(得分:1)

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>

答案 1 :(得分:1)

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

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

问题1:

  

如果jsonp需要回调,它是否实际使用了get但是从目标机器(websiteB)调用了get?   那么,jsonp实际上是指网站A将回调传递给websiteB而不是从websiteA发布到websiteB,而网站B实际上是在调用回调(实质上是指网站B正在调用网站A)?

回答问题1:

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

该服务将此功能输出为&#34;纯文本&#34;因为&lt; script&gt;期望在src=下找到有效的JavaScript。响应不能单独包含有效的JSON对象,因为&lt; script&gt;不负责分配变量,但是对于运行实际脚本以及如果远程服务将使用var weatherData = { ... }进行响应,则可以在客户端的上下文中访问weatherData。我不确定为什么 padding -function方法被认为更有利。可能是因为它更容易安全地解析。

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将网站A中的信息发布到网站B.或者我是否必须在websiteB服务器上启用CORS然后使用ajax的帖子和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