Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error 400 (Bad Request) when Using Batching #178

Open
Guseff opened this issue May 6, 2024 · 3 comments
Open

Error 400 (Bad Request) when Using Batching #178

Guseff opened this issue May 6, 2024 · 3 comments

Comments

@Guseff
Copy link

Guseff commented May 6, 2024

Hello!

I'm using SP Rest Proxy v. 3.3.4. In case I make single request it works good. While I try to make request using batching it returns 400 error
Screenshot 2024-05-06 at 1 59 09 PM

When deployed to env batching works. The problem presents only when the application is running locally.

Code looks like how it described here: https://pnp.github.io/pnpjs/concepts/batching/#advanced-batching
Screenshot 2024-05-06 at 2 04 55 PM
and baseUrl === 'http://localhost:8080'

I tried to utilise SP url from __webAbsoluteUrl, that I received using loadPageContext util. In this case it returns 403 error:
Screenshot 2024-05-06 at 2 21 03 PM
Url in __webAbsoluteUr is correct SP URL.

Could you, please, give me a pease of advice how to handle this?

@koltyakov
Copy link
Owner

koltyakov commented May 6, 2024

Hi @Guseff,

There is the thing with batch requests. They are processed inside SharePoint API backend, the multipart body contains a list or API calls which should have hostnames known by the SharePoint/farm.

When you use the proxy you route API calls to its host and it routes to SharePoint injecting Authentication headers/cookies/etc. to SharePoint:

Frontend (http://localhost:3000) ---[api request]--> Proxy (http://localhost:8080/sites/site-a/_api/web) ---> SharePoint Server (https://contoso.sharepoint.com/sites/site-a/_api/web)

http://localhost:3000 in that case is the frontend dev server address.
http://localhost:8080 is the stand along proxy (it can be a part of dev server, or routed through it). The app doesn't know anything about https://contoso.sharepoint.com/sites/site-a/_api/web thinking that http://localhost:8080/sites/site-a/_api/web is SharePoint entry.

The batch API requests's body should contain https://contoso.sharepoint.com/sites/site-a or http://localhost:8080/sites/site-a, URL path part should be valid, e.g. not http://localhost:8080/_api/web.

The localhost addresses then are replaced by this method https://github.com/koltyakov/sp-rest-proxy/blob/master/src/core/routers/restBatch.ts#L35 to https://contoso.sharepoint.com so SharePoint API then knows the host.

That said, make sure that what's inside batch API call body is valid.

My guess is that:

  • you have connected a site /sites/site-a (in proxy auth config)
  • but then call a root one / (in the application code)

The solution would be to initiate PnPjs const web = Web('http://localhost:8080/sites/site-a'); explicitly with web absolute address (proxy's host and site path: http://localhost:8080/sites/site-a), otherwise you send requests to the root site instead your application hosting site.

@Guseff
Copy link
Author

Guseff commented May 7, 2024

Hi, Andrew @koltyakov!

As I understand, I initialise sp variable using http://localhost:8080 base url. And in batch request body I have urls with this base:
Screenshot 2024-05-07 at 8 36 58 PM
And I need to replace http://localhost:8080 in this body with a real sp-site url. But I don't understand how I can do that. It looks like the approach described here #42 is deprecated and don't work at the moment.

I try to use batched web (https://pnp.github.io/pnpjs/concepts/batching/#using-a-batched-web) but it doesn't work too.

@koltyakov
Copy link
Owner

koltyakov commented May 7, 2024

Hey @Guseff,

So you confirmed the guess that it's:

  • you have connected a site /sites/site-a (in proxy auth config)
  • but then call a root one / (in the application code)

And the solution suggested is still actual.

The solution would be to initiate PnPjs const web = Web('http://localhost:8080/sites/site-a');

When you use non-batched queries the proxy replaces / to the contextual site (/sites/site-a, from auth configuration).

With batched queries this is not an option and you should explicitly define you're working with specific site: https://github.com/koltyakov/sp-rest-proxy?tab=readme-ov-file#load-page-context-helper

import { loadPageContext } from 'sp-rest-proxy/dist/utils/env';

// ...

// In both localhost and published to SharePoint page
await loadPageContext(); // `_spPageContextInfo` will contain correct info for vital props

// PnPjs's Web object should be created in the following way
const web = new Web(_spPageContextInfo.webAbsoluteUrl); // check if this still relevant with PnPjs
// _spPageContextInfo.webAbsoluteUrl -> http://localhost:8080/sites/site-a

// Then goes ordinary PnPjs code
const batch = web.createBatch();

const list = web.getList(`${_spPageContextInfo.webServerRelativeUrl}/List/ListName`);
const entityName = await list.getListItemEntityTypeFullName();

[1, 2, 3, 4].forEach((el) => {
  list.items.inBatch(batch).add({
    Title: `${el}`
  }, entityName);
});

await batch.execute();
console.log('Done');

P.S. Batches aren't usually worth using them. They ending up with the same throttling hits. I've rarely seen any benefits from batches to be honest, but more complex error handling.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants