web-dev-qa-db-fra.com

Raison bloquée de la demande d'origine croisée: le canal de contrôle en amont CORS n'a pas abouti

J'ai créé une application phonegap où j'appelle un service WCF qui réside dans le plugin nopCommerce.

Je reçois une erreur de suivi lors de l'envoi d'une demande d'api:

Demande d'origine croisée bloquée: la règle d'origine identique interdit la lecture de la ressource distante à l'adresse http://testwebsite.com/Plugins/NopRestApi/RemoteService/WebService.svc/GetData . (Raison: le canal de contrôle en amont CORS n'a pas abouti).

Demande d'origine croisée bloquée: la règle d'origine identique interdit la lecture de la ressource distante à l'adresse http://testwebsite.com/Plugins/NopRestApi/RemoteService/WebService.svc/GetData . (Raison: la requête CORS a échoué).

Appel d'API avec Ajax

$.ajax({
  crossDomain: true,
  type: "POST",
  contentType: "application/json",
  async: false,
  url: "http://testwebsite.com/Plugins/NopRestApi/RemoteService/WebService.svc/GetData",
  data: "{storeId:" + storeId + ", languageId:" + languageId + ", customerId:" + customerId + "}",            
  //data: { storeId: storeId, languageId: languageId, customerId: customerId },
  dataType: 'json',
  //jsonp: false,
  success: function (data) {
      alert(data.d);                
  },
  error: function (xhr, textStatus, error) {
      alert("Error! " + error);                
  }
});

J'ai ajouté suite à des recherches sur Google dans mon fichier Web.config.

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

J'ai essayé de nombreuses façons, même avec un navigateur désactivé, de vérifier la demande d'origine en suivant le lien { Comment désactiver temporairement la protection XSS dans les navigateurs modernes? } Mais le même problème persiste.

Quelqu'un at-il un problème similaire et résolu?

Merci!

6
Mayank Modi

Dans global.asax:

Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
    ' Fires at the beginning of each request
    If Request.HttpMethod = "OPTIONS" Then
        Response.Flush()
    End If

End Sub

Et la méthode allow de web.config show ajoute également des options.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <add key="aspnet:MaxJsonDeserializerMembers" value="1000000" />
  </appSettings>

  <connectionStrings/>
  <system.web>
    <compilation debug="true" strict="false" explicit="true" targetFramework="4.5.1"/>
    <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID">
      <namespaces>
        <clear/>
        <add namespace="System"/>
        <add namespace="System.Collections"/>
        <add namespace="System.Collections.Specialized"/>
        <add namespace="System.Configuration"/>
        <add namespace="System.Text"/>
        <add namespace="System.Text.RegularExpressions"/>
        <add namespace="System.Web"/>
        <add namespace="System.Web.Caching"/>
        <add namespace="System.Web.SessionState"/>
        <add namespace="System.Web.Security"/>
        <add namespace="System.Web.Profile"/>
        <add namespace="System.Web.UI"/>
        <add namespace="System.Web.UI.WebControls"/>
        <add namespace="System.Web.UI.WebControls.WebParts"/>
        <add namespace="System.Web.UI.HtmlControls"/>
      </namespaces>
    </pages>
    <authentication mode="Windows"/>
    <webServices>
      <protocols>
        <add name="HttpGet"/>
        <add name="HttpPost"/>
      </protocols>
    </webServices>
  </system.web>
  <system.webServer>
    <staticContent>
      <mimeMap fileExtension=".apk" mimeType="application/octet-stream"/>
    </staticContent>
  <handlers>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0"/>
      <remove name="OPTIONSVerbHandler"/>
      <remove name="TRACEVerbHandler"/>
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0"/>
    </handlers>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Methods" value="POST,OPTIONS,GET"/>
        <add name="Access-Control-Allow-Headers" value="Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With, Accept"/>
        <add name="Access-Control-Allow-Origin" value="*"/>
      </customHeaders>
    </httpProtocol>
  </system.webServer>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-Microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="System.Web.Cors" publicKeyToken="31BF3856AD364E35" culture="neutral"/>
                <bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0"/>
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
  <system.web.extensions>
    <scripting>
      <webServices>
        <jsonSerialization maxJsonLength="4000000" />
      </webServices>
    </scripting>
  </system.web.extensions>

</configuration>

Désolé que le fichier global.asax soit dans VB parce que je suis un gars VB, je pense que vous pouvez le convertir en C #.

Selon votre demande, mettez à jour comme suit:

function funCheckWS() {
    var tblLogin = {};
    tblLogin.strLoginName = "UserName";
    tblLogin.strPassword = "123456";
    jQuery.support.cors = true;
    $.ajax({
        type: 'POST',
        url: 'http://www.example.com/wsMain.asmx/funCheckWS',
        data: "{tblLogin:" + JSON.stringify(tblLogin) + "}",
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        crossDomain: true,
        // async: false,
        async: true,
        success: function (r) {
            // Browser support WS
            gloBolWS = true;
            // alert("funCheck: " + r.d.strPassword);
        },
        error: function (xhr, ajaxOptions, thrownError) {
            // Browser does not support WS
            //alert(xhr.status);
            //alert(thrownError);
        }
    });
}

Ci-dessous se trouvent mes services Web dans VB (la classe clsSQL est une classe écrite en VB qui contient des fonctions de toutes mes logiques d’entreprise backend et qui peut accéder au serveur SQL):

Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.ComponentModel
Imports System.Web.Script.Serialization
Imports System.Web.Script.Services
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Web

<System.Web.Script.Services.ScriptService()> _
<System.Web.Services.WebService(Namespace:="http://tempuri.org/")> _
<System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<ToolboxItem(False)> _
Public Class wsMain
    Inherits System.Web.Services.WebService

    Private clsSQL As New wxdlSQL.clsSQL()

    Private tblLogin As tabLogin
    <WebMethod()> _
    <ScriptMethod(ResponseFormat:=ResponseFormat.Json)> _
    Public Function funCheckWS(tblLogin As tabLogin) As tabLogin
        tblLogin.strLoginName += "Hello World"
        Return tblLogin
    End Function
End Class

Voici comment je définit le type de données pour les paramètres:

Public Class tabLogin
    Private _loginname As String
    Public Property strLoginName As String
        Get
            Return _loginname
        End Get
        Set(ByVal value As String)
            _loginname = value
        End Set
    End Property
    Private _password As String
    Public Property strPassword As String
        Get
            Return _password
        End Get
        Set(ByVal value As String)
            _password = value
        End Set
    End Property
End Class
3
Kenneth Li

Vous devez autoriser les requêtes interdomaines à partir de votre service WCF. 

Response.AppendHeader("Access-Control-Allow-Origin", "*");

ajoutez ceci dans votre fonction mais ajoutez ceci avant que vos données retournent de fonction.

Comment implémenter l'en-tête "Access-Control-Allow-Origin" dans asp.net pourrait être utile.

3
Vinit Patel

Dans votre Global.asax, ajoutez le code suivant:

protected void Application_AuthenticateRequest(object sender, EventArgs e){
    Response.AddHeader("Access-Control-Allow-Origin", "*");
    if (Context.Request.HttpMethod.Equals("OPTIONS")){
        Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
        Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        Response.StatusCode = (int)System.Net.HttpStatusCode.OK;
        Context.ApplicationInstance.CompleteRequest();
     }
 }

Cela devrait fonctionner

1
Esha Wali