我有两个站点
我也有一个webservice.
当我在:http://www.mydomain.com/trouwlocaties/zoeken-uitgebreid
上通过级联下拉菜单加载国家名称时,就可以看到这个效果了然而,同样的web服务在:http://otherdomain.com/weddingvenues/search-advanced上抛出错误正如你所看到的下拉菜单显示'方法错误-1',在我的Chrome控制台中我看到:500(内部服务器错误),其中客户端试图获取.asmx服务,在toptrowen上它使用POST(这是我相信应该发生的事情,也更安全)。
这是getnations webservice:
<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。经过一些Google搜索,我认为这与MIME类型有关,但我从来没有发现如何将此服务更改为XML。
所以我继续搜索,发现了一些别的东西,我正在阅读这些帖子:http://social.msdn.microsoft.com/forums/en-us/asmxandxml/thread/F80BDA62-C87A-4BDA-8CB1-F2CFAD1C8891未捕获的SyntaxError: Unexpected token <——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
更新了我的网页。配置:
<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中的WITH协议部分。配置
<webServices>
<protocols>
<remove name="Documentation"/>
<add name="HttpGet"/>
<add name="HttpPost"/>
</protocols>
</webServices>
在。nl域名上正确工作在。com域上抛出方法错误-1。Chrome控制台显示:Uncaught SyntaxError: Unexpected token 场景2:web中没有协议部分。配置 在。nl域名上正确工作在。com域上抛出方法错误-1。Chrome控制台显示:GET http://www.otherdomain.com/geolocation.asmx/GetCountries?knownCategoryValues=%22%22&category=%22Country%22&callback=Sys._jsonp0 500 (Internal Server Error) ScriptResource.axd:7773 使用此方法定义的场景3和4: 场景3:web.config 在。nl域上抛出方法错误500。Chrome控制台显示:POST http://www.mydomain.com/geolocation.asmx/GetCountries 500(内部服务器错误)catch .js:197在。com域名下拉列表中抛出方法错误-1。Chrome控制台显示:Uncaught SyntaxError: Unexpected token 场景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 (Internal Server Error) 我也没有显式地从脚本中调用.asmx,我让级联下拉为我做这项工作。像这样: 后台代码 我不知道我使用这些预定义元素的事实是否与我的问题有关,我可以更好地通过脚本自己调用.asmx服务并填充下拉列表。如果是,我不知道怎么做。<WebMethod()> _
<ScriptMethod(UseHttpGet:=True, ResponseFormat:=System.ServiceModel.Web.WebMessageFormat.Json)> _
Public Function GetCountries(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
<webServices>
<protocols>
<remove name="Documentation"/>
<add name="HttpGet"/>
<add name="HttpPost"/>
</protocols>
</webServices>
<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"
你是正确的,这是一个跨原产地的问题。有几种方法可以处理这个问题:
您可以将web服务转换为JSONP,只要需要转到web服务的数据不是非常大。来自服务的数据可以像你喜欢的那样大。不要太大,它必须是大约2k个字符或更少-您可以通过知道它是作为从脚本标记的src属性的get请求的一部分发送的,来计算一个JSONP请求中可以发送的数据量。
这里有一个很好的关于JSONP的答案,你可能已经很熟悉了:
JSONP是关于什么的?
更新strong>
下面是一个在VB中做JSONP的例子。净:http://www.sattsoft.com/tutorials/contents/1/14/cross-domain-call-using-ajax-jquery-jsonp-and-vb-net-web-service.html您可以创建www.wunderweddings.com的子域,也许称之为"api.www.wunderweddings.com",并使用DNS使用a或CNAME记录将该子域指向正确的位置。然后,您将嵌入一个微小的(不可见的)iframe到您的客户端页面,它将指向这个新的api主机(一定要指定src为"//api.www.underweddings.com",以便匹配包含页面的http/s),并在iframe中使用javascript来推广其文档。域到www.wunderweddings.com,你可以通过脚本注入,但它更容易只是有该页面在服务器上提供的脚本来做,然后你可以自由地通信之间的iframe指向你的API和包含iframe的页面是www.wunderweddings.com。iframe中的代码会为你访问web服务,获取数据,推广文档。域,并通知包含该页。
如果你知道postMessage在你的客户端总是可用的(可能不是虽然),你可以做上面没有改变document.domain
上面的第2点和第3点可能听起来很麻烦!特别是如果你打算扩展你提供的web服务和/或访问该服务的域的数量。如果是这样,我强烈推荐使用EasyXDM,它是一个非常棒的、非常强大的库,用于执行客户端跨域RPC:
http://easyxdm.net/wp/EasyXDM在postMessage不可用的情况下提供了回退,例如通过散列或name属性进行通信,以及其他一些事情。
你可以修复crossdomain.xml。这是我有点生疏的地方,但我会给你我最好的猜测:
更新strong>
你希望你的crossdomain.xml像这样:
<?xml version="1.0" ?>
<cross-domain-policy>
<allow-access-from domain="*" />
<allow-access-from domain="*.wunderweddings.com" />
</cross-domain-policy>
"
我不知道为什么配置的东西在那里,它不应该在那里。我第一次完全没有注意到,这几乎肯定是你的问题。还要确保crossdomain.xml是从另一个服务器(具有web服务的服务器)提供的。
澄清一下,crossdomain。XML底部不应该有额外的XML
最终更新
对于那些有类似问题的人来说,Floran发现了无效字符的问题:
这个必须被添加到页面的顶部:
<asp:ScriptManagerProxy ID="ScriptManagerProxy1" runat="server">
<Services>
<asp:ServiceReference Path="geolocation.asmx" />
</Services>
</asp:ScriptManagerProxy>