我有2个网站。
我也有网络服务。
当我在级联下拉菜单中加载国家/地区名称时,您可以看到此操作:http://www.mydomain.com/trouwlocaties/zoeken-uitgebreid
但是,同一个Web服务会抛出错误:http://otherdomain.com/weddingvenues/search-advanced 你可以看到下拉列表显示'方法错误-1',在我的Chrome控制台中,我看到:500(内部服务器错误),客户端尝试获取.asmx服务,在toptrouwen上使用POST(就像我一样)相信应该发生什么,也更安全。)
这是GetCountries网络服务:
<System.Web.Script.Services.ScriptService()> _
<System.Web.Services.WebService(Namespace:="http://tempuri.org/")> _
<System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
<ToolboxItem(False)> _
Public Class geolocation
'<System.Web.Script.Services.ScriptService()> _
'<WebService(Namespace:="http://tempuri.org/")> _
'<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
'<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Inherits System.Web.Services.WebService
<WebMethod()> _
Public Function GetCountries(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
Dim values As New List(Of CascadingDropDownNameValue)
Dim myConnection As SqlConnection = GetConnection()
Dim cmd As New SqlCommand(String.Format("SELECT id,name as title FROM country order by title asc", Threading.Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName), myConnection)
Try
myConnection.Open()
Dim reader As SqlDataReader = cmd.ExecuteReader
Dim CountryName As String
Dim CountryID As Integer
While reader.Read
CountryName = reader("title").ToString
Int32.TryParse(reader("id"), CountryID)
values.Add(New CascadingDropDownNameValue(CountryName, CountryID.ToString))
End While
Catch ex As Exception
Finally
myConnection.Close()
End Try
Return values.ToArray
End Function
End Class
首先我尝试将其添加到我的web.config:
<system.web>
<webServices>
<protocols>
<remove name="Documentation"/>
<add name="HttpGet"/>
<add name="HttpPost"/>
</protocols>
</webServices>
</system.web>
完成此操作后,我在Chrome控制台中收到了此消息:
Uncaught SyntaxError: Unexpected token <
显然结果不是解释为XML,但我的猜测是JSON。经过一些谷歌搜索后,我认为这与MIME类型有关,但我从未发现如何将此更改为XML服务。
所以我继续搜索并发现其他内容,我正在阅读这些帖子: http://social.msdn.microsoft.com/forums/en-us/asmxandxml/thread/F80BDA62-C87A-4BDA-8CB1-F2CFAD1C8891 Uncaught SyntaxError: Unexpected token < -- in jQuery ajax
显然这可能是一个“跨域问题”。
所以我最终创建了这些文件:
clientaccesspolicy.xml
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="*">
<domain uri="*"/>
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
的crossdomain.xml
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<?xml version="1.0" ?>
<cross-domain-policy>
<allow-access-from domain="*" />
<allow-access-from domain="*.otherdomain.com" secure="false" />
</cross-domain-policy>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="GetCountries" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://www.mydomain.com/geolocation.asmx"
binding="basicHttpBinding" name="GeoLocation" />
</client>
</system.serviceModel>
</configuration>
在第一个示例链接中,用户还添加了属性bindingConfiguration =“DashboardServiceSoap”和contract =“DashboardService.DashboardServiceSoap”,但我不知道在我的情况下我必须填写什么。
我仍然卡住了,我不知道什么是正确的音轨以及如何配置我的设置。
更新21-06-2013
使用以下内容更新了我的web.config:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
</customHeaders>
</httpProtocol>
我还尝试了以下4种配置:
<System.Web.Script.Services.ScriptService()> _
<System.Web.Services.WebService(Namespace:="http://tempuri.org/")> _
<System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
<ToolboxItem(False)> _
Public Class geolocation
Inherits System.Web.Services.WebService
场景1和2使用此方法定义:
<WebMethod()> _
Public Function GetCountries(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
方案1:web.config中的WITH protocols部分
<webServices>
<protocols>
<remove name="Documentation"/>
<add name="HttpGet"/>
<add name="HttpPost"/>
</protocols>
</webServices>
在.nl域上正常工作 在.com域上引发方法错误-1。 Chrome控制台显示:未捕获的SyntaxError:意外的令牌&lt;的getCountries:1
场景2:web.config中没有协议部分
在.nl域上正常工作 在.com域上引发方法错误-1。 Chrome控制台显示:GET http://www.otherdomain.com/geolocation.asmx/GetCountries?knownCategoryValues=%22%22&category=%22Country%22&callback=Sys._jsonp0 500(内部服务器错误)ScriptResource.axd:7773
使用此方法定义的方案3和4:
<WebMethod()> _
<ScriptMethod(UseHttpGet:=True, ResponseFormat:=System.ServiceModel.Web.WebMessageFormat.Json)> _
Public Function GetCountries(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
方案3:web.config中的WITH protocols部分
<webServices>
<protocols>
<remove name="Documentation"/>
<add name="HttpGet"/>
<add name="HttpPost"/>
</protocols>
</webServices>
在.nl域上引发方法错误500。 Chrome控制台显示:POST http://www.mydomain.com/geolocation.asmx/GetCountries 500(内部服务器错误)catcher.js:197 在下拉列表中的.com域上引发方法错误-1。 Chrome控制台显示:未捕获的SyntaxError:意外的令牌&lt;的getCountries:1
场景4:web.config中没有协议部分
在.nl域上引发方法错误500。 Chrome控制台显示:无法加载资源:服务器响应状态为500(内部服务器错误) 在下拉列表中的.com域上引发方法错误-1。 Chrome控制台显示:GET http://www.otherdomain.com/geolocation.asmx/GetCountries?knownCategoryValues=%22%22&category=%22Country%22&callback=Sys._jsonp0 500(内部服务器错误)
此外,我并没有明确地从脚本调用.asmx,我让级联下拉列表为我工作。像这样:
<asp:DropDownList ID="ddlCountries" CssClass="textbox" AutoPostBack="true" runat="server"></asp:DropDownList>
<cc1:cascadingdropdown ID="cddCountries" runat="server" Category="Country" Enabled="True" LoadingText="<%$Resources:Glossary,loading %>" PromptText="<%$Resources:Glossary,country_choose %>"
ServiceMethod="GetCountries" TargetControlID="ddlCountries">
</cc1:cascadingdropdown>
代码隐藏
cddCountries.ServicePath = "http://www.mydomain.com/geolocation.asmx"
我不知道我使用这些预定义元素的事实是否与我的问题有关,我最好自己通过脚本调用.asmx服务并填写下拉列表。如果是这样的话:我不知道该怎么做。
答案 0 :(得分:1)
你是对的,这是一个跨领域的问题。有几种方法可以解决这个问题:
只要需要转到Web服务的数据不是很大,您就可以将Web服务转换为JSONP。来自服务的数据可以尽可能大。通过非常大,它必须大约2k字符或更少 - 您可以通过知道它是作为来自脚本标记的src属性的get请求的一部分发送的,在一个JSONP请求中计算可以发送的数据量。
以下是您可能已经熟悉的JSONP的优秀答案:
更新
以下是在VB.NET中执行JSONP的示例:
您可以创建www.wunderweddings.com的子域名,也可以将其命名为“api.www.wunderweddings.com”并使用DNS将该子域名指向正确的位置,使用A或CNAME记录。然后你会在你的客户端页面中嵌入一个小的(不可见的)iframe,指向这个新的api主机(确保将src指定为“//api.www.underweddings.com”以便匹配http / s包含页面的内容),并使用iframe中的javascript将其document.domain推广到www.wunderweddings.com,你可以通过脚本注入来完成它,但它更容易让服务器上的那个页面提供脚本来完成它,然后您可以在指向您的api的iframe和包含www.wunderweddings.com的iframe的页面之间自由交流。因此,iframe中的代码将为您访问Web服务,获取数据,提升其document.domain,并通知包含页面。
如果您知道postMessage始终可以在您的客户端上使用(可能不是),您可以在不更改document.domain的情况下执行上述操作。
上面的第2点和第3点可能听起来很麻烦!特别是如果您打算扩展您提供的Web服务和/或访问该服务的域的数量。如果是这样,我非常强烈建议使用EasyXDM,它是一个非常强大且非常强大的库,用于执行客户端跨域RPC:
EasyXDM提供postMessage的后备,如果它不可用,例如通过散列或name属性进行通信,以及其他一些内容。
您可以修复crossdomain.xml。现在这里我有点生疏,但我会给你最好的猜测:
<强>更新强>
您希望您的crossdomain.xml像这样:
<?xml version="1.0" ?>
<cross-domain-policy>
<allow-access-from domain="*" />
<allow-access-from domain="*.wunderweddings.com" />
</cross-domain-policy>
“&lt; cross-domain-policy&gt;”的第一个孩子,即“&lt; allow-access-from domain =”“/&gt;”将使它完全不受限制,而“&lt; allow-access-from domain =” .wunderweddings.com“/&gt;”只有wunderweddings.com和子域才允许浏览器进行跨域调用。您不需要两个“allow-access-from”标记,但至少需要其中一个标记。
我不确定为什么配置的东西在那里,它不应该。我完全没有注意到第一次,这几乎肯定是你的问题。还要确保从其他服务器(具有Web服务的服务器)提供crossdomain.xml。
所以只是为了澄清一下,crossdomain.xml不应该在底部有额外的XML,&lt; onfiguration&gt; ...&lt; / configuration&gt;标签及其中的所有内容,所有这些都是从某个地方泄漏而不应该在crossdomain.xml内部
最终更新
对于那些有类似问题的人来说,Floran发现了无效字符的问题:
这必须添加到页面顶部:
<asp:ScriptManagerProxy ID="ScriptManagerProxy1" runat="server">
<Services>
<asp:ServiceReference Path="geolocation.asmx" />
</Services>
</asp:ScriptManagerProxy>