服务仅有时会引发 No 'Access-Control-Allow-Origin' 标头错误

Posted

技术标签:

【中文标题】服务仅有时会引发 No \'Access-Control-Allow-Origin\' 标头错误【英文标题】:Service only sometimes throws No 'Access-Control-Allow-Origin' header error服务仅有时会引发 No 'Access-Control-Allow-Origin' 标头错误 【发布时间】:2015-02-22 06:10:51 【问题描述】:

我有一个包含多种方法的服务。我将我的 Global.asax 文件设置为处理 CORS,过去一切正常,包括 CORS……直到我将以下内容添加到接口文件中:

[OperationContract]
[WebInvoke(UriTemplate = "/Transform", Method = "POST", ResponseFormat = WebMessageFormat.Json)]
bool XXXTransform(string user, string x);

以及以下服务类...

bool XXXTransform(string user, string x)

    return true;

现在,真正有趣的事情来了。当我调用 GetRecipes 方法时会发生错误。更有趣的是,如果我只为接口和服务类的 XXXTransform 指定了一个参数,它不会抛出错误 - 就像在 bool XXXTransform(string user) 中一样

以前有人见过这样的事情吗?为什么使用一个参数会起作用,但是调用完全不同的方法时,两个参数会导致原点错误?

IChomp.cs:

namespace NomNomNotebookService

    // May need to mod service behavior for upload...
    [ServiceContract]
    public interface IChomp
    
        [OperationContract]
        [WebInvoke(UriTemplate = "/userId/Recipes", Method = "GET", ResponseFormat = WebMessageFormat.Json)]
        List<Recipe> GetRecipes(string userId);

        [OperationContract]
        [WebInvoke(UriTemplate = "/userId/Recipes", Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        Recipe AddRecipe(string userId, Recipe recipe);

        [OperationContract]
        [WebInvoke(UriTemplate = "/userId/Recipes/recipeId", Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        Recipe UpdateRecipe(string userId, string recipeId, Recipe recipe);

        [OperationContract]
        [WebInvoke(UriTemplate = "/userId/Recipes/recipeId", Method = "DELETE", BodyStyle = WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json)]
        bool DeleteRecipe(string userId, string recipeId);

        [OperationContract]
        [WebInvoke(UriTemplate = "/userId/Recipes/recipeId", Method = "GET", ResponseFormat = WebMessageFormat.Json)]
        Recipe GetRecipe(string userId, string recipeId);

        [OperationContract]
        [WebInvoke(UriTemplate = "/Categories", Method = "GET", ResponseFormat = WebMessageFormat.Json)]
        List<Category> GetCategories();

        [OperationContract]
        [WebInvoke(UriTemplate = "/Upload", Method = "POST", ResponseFormat = WebMessageFormat.Json)]
        bool XXXUpload();

        [OperationContract]
        [WebInvoke(UriTemplate = "/Transform", Method = "POST", ResponseFormat = WebMessageFormat.Json)]
        bool XXXTransform(string user, string x); // WILL work if I have bool XXXTransform(string user)
    

Chomp.cs

namespace NomNomNotebookService

    public class Chomp : IChomp
    
        private DBConnector _dbCon = new DBConnector();

        public List<Recipe> GetRecipes(string userId)
        
            _dbCon.Parameters.Add(new CustSqlParam("@userId", Int16.Parse(userId)));
            DataTable dt = _dbCon.RunProc("J_NNN_GetRecipesForUser");

            List<Recipe> recipes = new List<Recipe>();
            foreach (DataRow row in dt.Rows)
            
                recipes.Add(new Recipe((int)row["Uid"], (string)row["Name"], (string)row["Description"], (string)row["Category"]));
            

            _dbCon.Kill();

            return recipes;
        

        public Recipe GetRecipe(string userId, string recipeId)
        
            _dbCon.Parameters.Add(new CustSqlParam("@uid", Int16.Parse(recipeId)));
            DataTable dt = _dbCon.RunProc("J_NNN_GetRecipe");

            Recipe recipe = new Recipe(dt.Rows[0]);
            _dbCon.Kill();

            return recipe;
        

        // USER ID IS HERE FOR VALIDATION ONCE SESSIONS ARE ROLLING
        public Recipe AddRecipe(string userId, Recipe recipe)
        
            _dbCon.Parameters.Add(new CustSqlParam("@userId", Int16.Parse(userId)));
            _dbCon.Parameters.Add(new CustSqlParam("@name", recipe.Name));
            _dbCon.Parameters.Add(new CustSqlParam("@description", recipe.Description));
            _dbCon.Parameters.Add(new CustSqlParam("@categoryId", recipe.Category.Uid));
            _dbCon.Parameters.Add(new CustSqlParam("@prepTime", recipe.PrepTime));
            _dbCon.Parameters.Add(new CustSqlParam("@cookTime", recipe.CookTime));
            _dbCon.Parameters.Add(new CustSqlParam("@readyTime", recipe.ReadyTime));

            DataTable dt = _dbCon.RunProc("J_NNN_AddRecipe");
            _dbCon.Kill();
            return new Recipe(dt.Rows[0]);
        

        public Recipe UpdateRecipe(string userId, string recipeId, Recipe recipe)
        
            _dbCon.Parameters.Add(new CustSqlParam("@uid", Int16.Parse(recipeId)));
            _dbCon.Parameters.Add(new CustSqlParam("@name", recipe.Name));
            _dbCon.Parameters.Add(new CustSqlParam("@description", recipe.Description));
            _dbCon.Parameters.Add(new CustSqlParam("@categoryId", recipe.Category.Uid));
            _dbCon.Parameters.Add(new CustSqlParam("@prepTime", recipe.PrepTime));
            _dbCon.Parameters.Add(new CustSqlParam("@cookTime", recipe.CookTime));
            _dbCon.Parameters.Add(new CustSqlParam("@readyTime", recipe.ReadyTime));

            DataTable dt = _dbCon.RunProc("J_NNN_UpdateRecipe");
            _dbCon.Kill();
            return new Recipe(dt.Rows[0]);
        

        public bool DeleteRecipe(string userId, string recipeId)
        
            try
            
                _dbCon.Parameters.Add(new CustSqlParam("@uid", Int16.Parse(recipeId)));
                DataTable dt = _dbCon.RunProc("J_NNN_DeleteRecipe");
                _dbCon.Kill();
            
            catch (Exception e)
            
                Console.WriteLine(e.ToString());
                return false;
            
            return true;
        

        public List<Category> GetCategories()
        
            DataTable dt = _dbCon.RunProc("J_NNN_GetCategories");
            _dbCon.Kill();

            List<Category> categories = new List<Category>();
            foreach (DataRow row in dt.Rows)
            
                categories.Add(new Category((int)row["Uid"], (string)row["Name"]));
            

            return categories;
        

        // Upload shit....
        public bool XXXUpload()
        
            return false;
        

        public bool XXXTransform(string user, string x) // WILL work if I have bool XXXTransform(string user)
        

            return true;
        
    

全球.asax

namespace NomNomNotebookService

    public class Global : System.Web.HttpApplication
    
        protected void Session_Start(object sender, EventArgs e)
        
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
            if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
            
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
                HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
                HttpContext.Current.Response.End();
            
        
    

【问题讨论】:

能看到实际的代码OP吗? 另外,如果需要对我未包含的类文件进行任何说明,请随时指出——不过,它应该很简单。 如果它谈到基于 Rest 的 Web API 中的类似问题,请查看此链接:***.com/questions/27373165/… 似乎是一个安全问题。我还在研究它。 @MrinalKamboj - 我的 Global.asax 文件处理所有请求的动词,它工作正常......直到我开始使用最后一种方法的 2 个参数。 【参考方案1】:

我过去也遇到过类似的错误。您的配置中是否设置了请求标头?

'Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS'
'Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With'

【讨论】:

是的,我的 Global.asax 文件运行良好。但是,如果最后一个方法有 2 个参数,我会得到错误。只有一个,它工作正常 @jimelrod 你的服务有过滤器吗? 因为我不确定在这种情况下过滤器是什么......我假设不是?

以上是关于服务仅有时会引发 No 'Access-Control-Allow-Origin' 标头错误的主要内容,如果未能解决你的问题,请参考以下文章

命名管道上的 WriteFile 有时会返回 ERROR_NO_DATA

标准排序有时会引发分段错误

当 cp 没有时,为啥 shutil.copy() 会引发权限异常?

php图片裁剪

Python OpenCV 人脸检测代码有时会引发“元组”对象没有属性“形状”

仅有时解析服务器 S3 图像上传 - 套接字问题